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); } } }