Untiy 多线程方式实现延时函数(C#)
协程方式或者Invoke方式实现的延时函数要集成MonoBehavior,如果恰巧你的场景不符合这个,就可以用多线程方式来实现延时。
原理是创建一个Task ,利用Task的Delay方法来实现延时。
如果mainThreadCallback为true,就强制使用Loom来切回主线程。(Loom在网上可以搜到)
否则默认获取调用延时函数的线程来执行回调
但也会遇到执行回调时线程已经关闭的情况,这样就直接用执行task的线程来执行回调方法
如果想中途取消,则用CancellationTokenSource 来接着它,然后调用.Cancel()就可以了
/// 延时函数,多线程方法实现。想取消就用一个值接着它,执行Cancel()就可以了
/// </summary>
/// <param name="second">延时秒数</param>
/// <param name="callback">延时执行的语句</param>
/// <param name="mainThreadCallback">为true,则回调强制切回主线程再传回来</param>
/// <returns></returns>
public static CancellationTokenSource Delay(float second, System.Action callback, bool mainThreadCallback = false)
{
CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
//获取当前线程(其实可能是主线程)
SynchronizationContext currentTheardc = SynchronizationContext.Current;
Task task = Task.Factory.StartNew(async () =>
{
await Task.Delay((int)(second * 1000));
//强制切回主线程
if (mainThreadCallback)
{
Loom.QueueOnMainThread(() => {
callback();
});
}
//如果“当前线程”没有丢失
else if (currentTheardc != null)
{
//通知”当前线程“做事
currentTheardc.Send(new SendOrPostCallback((ss) =>
{
callback();
}), null);
}
//如果“当前线程”意外丢失
else
{
callback();
}
}, cancelTokenSource.Token);
return cancelTokenSource;
}