Unity异步化_new unitaskcompletionsource()
UniTask
链接:UniTask/src/UniTask/Assets/Plugins/UniTask at master · Cysharp/UniTask · GitHub
Task
await
产生 GCTime.timeScale
向上优化Task,向下兼容协程。
命名空间
using Cysharp.Threading.Tasks;
与原生Task的API对比
UniTask.RunOnThreadPool
(不推荐,考虑是否能用UniTask.Create)
常用API
UniTask.Create
创建:该方法被调用的时候,立即创建一个新的UniTask
执行:UniTask在Create()被调用的那一刻就开始执行了
UniTask task = UniTask.Create( async ()=> { Debug.Log(\"Create\"); await UniTask.Delay(1000); Debug.Log(\"Complete\"); });
UniTask.Defer
创建:将UniTask创建延迟到await的时机
执行:只能await一次,但比Lazy轻量
UniTask task = UniTask.Defer( async () => { Debug.Log(\"Defer\"); await UniTask.Delay(1000); Debug.Log(\"Complete\"); });await defer;
UniTask.Lazy
创建:将UniTask创建延迟到await的时机
执行:创建AsyncLazy,AsyncLazy.Task可以被await任意次数,比Defer的成本更高
AsyncLazy asyncLazy = UniTask.Lazy( async () => { Debug.Log(\"AsyncLazy\"); await UniTask.Delay(1000); Debug.Log(\"Complete\"); });await asyncLazy.Task;await asyncLazy.Task;
UniTask与UniTaskVoid
UniTask
UniTaskVoid
await GetPlayerData()
)return score
)async void
风险)CancellationToken
)DOTween UniTask化
对Tween或Sequence动画可进行异步等待
public static class DOTweenExtensions { public static UniTask AwaitForComplete(this Tween tween, CancellationToken cancellationToken = default) { var tcs = new UniTaskCompletionSource(); try { tween.OnComplete(() => tcs.TrySetResult()); tween.OnKill(() => tcs.TrySetCanceled()); cancellationToken.Register(() => tween.Kill()); } catch (Exception e) { Debug.LogError($\"Tween AwaitForComplete Error: {e}\"); tcs.TrySetException(new Exception($\"DOTween AwaitForComplete Error: {e}\")); } return tcs.Task; }}// 使用方法: try { await sequence.AwaitForComplete(cancelToken); } catch (OperationCanceledException) { Debug.Log(\"Tween Canceled\"); } catch (Exception ex) { Debug.LogError($\"Tween Get Error: {ex}\"); }
Spine UniTask化
仅针对最常用的Spine.AnimationState.SetAnimation方法进行UniTask化。
该方法对循环动画的处理可自行定义。
本代码仅考虑了单轨道动画,对多轨道动画的实际表现未知。
public static class SpineExtensions { public static UniTask AwaitForComplete(this TrackEntry entry, Spine.AnimationState state = null, CancellationToken cancellationToken = default) { var tcs = new UniTaskCompletionSource(); try { if (!entry.Loop) { entry.Complete += _ => tcs.TrySetResult(); entry.End += _ => tcs.TrySetCanceled(); } else { entry.End += _ => tcs.TrySetResult(); } if (cancellationToken != default && state != null) { cancellationToken.Register(() => state.ClearTrack(entry.TrackIndex)); } } catch (Exception e) { Debug.LogError($\"TrackEntry AwaitForComplete Error: {e}\"); tcs.TrySetException(new Exception($\"Spine AwaitForComplete Error: {e}\")); } return tcs.Task; }}// 使用方法: try { TrackEntry entry = skeleton_animation.state.SetAnimation(0, animationName, loop); await entry.AwaitForComplete(skeleton_animation.state, cancelToken); } catch (OperationCanceledException) { Debug.Log(\"Animation Canceled\"); } catch (Exception ex) { Debug.LogError($\"Animation Get Error: {ex}\"); }
Task UniTask化
*.AsUniTask()
参考文章
https://zhuanlan.zhihu.com/p/572670728https://zhuanlan.zhihu.com/p/572670728spine-unity 运行时文档
https://zh.esotericsoftware.com/spine-unity