80 lines
2.4 KiB
C#
80 lines
2.4 KiB
C#
using UnityEngine;
|
||
using System.Collections.Generic;
|
||
|
||
namespace UnityThreadingUtils
|
||
{
|
||
/// <summary>
|
||
/// 用于在子线程中将任务安全地调度到Unity主线程执行的工具类
|
||
/// </summary>
|
||
public class UnityMainThreadDispatcher : MonoBehaviour
|
||
{
|
||
private static UnityMainThreadDispatcher _instance;
|
||
|
||
// 用于存储需要在主线程执行的任务队列
|
||
private readonly Queue<System.Action> _actionQueue = new Queue<System.Action>();
|
||
|
||
private void Awake()
|
||
{
|
||
if (_instance == null)
|
||
{
|
||
_instance = this;
|
||
// 让这个游戏对象在场景切换时不被销毁,确保持续可用
|
||
//DontDestroyOnLoad(gameObject);
|
||
}
|
||
else
|
||
{
|
||
//Destroy(gameObject);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取单例实例
|
||
/// </summary>
|
||
/// <returns>UnityMainThreadDispatcher单例对象</returns>
|
||
public static UnityMainThreadDispatcher Instance()
|
||
{
|
||
if (_instance == null)
|
||
{
|
||
// 创建一个新的游戏对象来挂载该组件
|
||
GameObject dispatcherGameObject = new GameObject("UnityMainThreadDispatcher");
|
||
_instance = dispatcherGameObject.AddComponent<UnityMainThreadDispatcher>();
|
||
// 让这个游戏对象在场景切换时不被销毁,确保持续可用
|
||
//UnityEngine.Object.DontDestroyOnLoad(dispatcherGameObject);
|
||
}
|
||
|
||
return _instance;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将一个任务添加到主线程执行的队列中
|
||
/// </summary>
|
||
/// <param name="action">需要在主线程执行的任务(以Action委托表示)</param>
|
||
public void Enqueue(System.Action action)
|
||
{
|
||
lock (_actionQueue)
|
||
{
|
||
_actionQueue.Enqueue(action);
|
||
}
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
// 加锁确保线程安全地处理任务队列
|
||
lock (_actionQueue)
|
||
{
|
||
while (_actionQueue.Count > 0)
|
||
{
|
||
System.Action action = _actionQueue.Dequeue();
|
||
try
|
||
{
|
||
action.Invoke();
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
//Debug.LogError($"执行主线程任务时出错: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |