using System;
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Threading;
using UnityEngine;
/// <summary>
/// Unity主线程工作队列
/// </summary>
public class UnityWorkQueue : MonoBehaviour
{
private Thread _mainAppThread = null;
private readonly ConcurrentQueue<Action> _mainThreadWorkQueue = new ConcurrentQueue<Action>();
public bool IsMainAppThread
{
get
{
UnityEngine.Debug.Assert(_mainAppThread != null, "This method can only be called once the object is awake.");
return Thread.CurrentThread == _mainAppThread;
}
}
[Conditional("UNITY_ASSERTIONS")]
public void EnsureIsMainAppThread()
{
UnityEngine.Debug.Assert(IsMainAppThread, "This method can only be called from the main Unity application thread.");
}
protected virtual void Awake()
{
// Awake()方法总是从Unity主线程调用(the main Unity app thread)
_mainAppThread = Thread.CurrentThread;
}
protected virtual void Update()
{
if (_mainThreadWorkQueue.TryDequeue(out Action workload))
{
workload();
}
}
public void InvokeOnAppThread(Action action)
{
if (_mainAppThread != null && IsMainAppThread)
{
action();
}
else
{
_mainThreadWorkQueue.Enqueue(action);
}
}
}