> 技术文档 > Unity异步化_new unitaskcompletionsource()

Unity异步化_new unitaskcompletionsource()


UniTask

链接:UniTask/src/UniTask/Assets/Plugins/UniTask at master · Cysharp/UniTask · GitHub

特性 传统 Task UniTask GC 分配 每次 await 产生 GC 零 GC 时间系统 依赖系统时钟 自动同步 Time.timeScale 线程安全 需手动回主线程 默认在主线程执行 性能 较慢 快 2-5 倍

向上优化Task,向下兼容协程。 

命名空间

using Cysharp.Threading.Tasks;

与原生Task的API对比

.NET 类型 UniTask 类型 IProgress --- CancellationToken --- CancellationTokenSource --- Task/ ValueTask UniTask Task/ ValueTask UniTask async void async UniTaskVoid += async () => { } UniTask.Void, UniTask.Action, UniTask.UnityAction --- UniTaskCompletionSource TaskCompletionSource UniTaskCompletionSource/ AutoResetUniTaskCompletionSource ManualResetValueTaskSourceCore UniTaskCompletionSourceCore IValueTaskSource IUniTaskSource IValueTaskSource IUniTaskSource ValueTask.IsCompleted UniTask.Status.IsCompleted() ValueTask.IsCompleted UniTask.Status.IsCompleted() new Progress Progress.Create CancellationToken.Register(UnsafeRegister) CancellationToken.RegisterWithoutCaptureExecutionContext CancellationTokenSource.CancelAfter CancellationTokenSource.CancelAfterSlim Channel.CreateUnbounded(false){ SingleReader = true} Channel.CreateSingleConsumerUnbounded IAsyncEnumerable IUniTaskAsyncEnumerable IAsyncEnumerator IUniTaskAsyncEnumerator IAsyncDisposable IUniTaskAsyncDisposable Task.Delay UniTask.Delay Task.Yield UniTask.Yield Task.Run

UniTask.RunOnThreadPool

(不推荐,考虑是否能用UniTask.Create)

--- UniTask.Create --- UniTask.Defer --- UniTask.Lazy Task.WhenAll UniTask.WhenAll Task.WhenAny UniTask.WhenAny Task.CompletedTask UniTask.CompletedTask Task.FromException UniTask.FromException Task.FromResult UniTask.FromResult Task.FromCanceled UniTask.FromCanceled Task.ContinueWith UniTask.ContinueWith TaskScheduler.UnobservedTaskException UniTaskScheduler.UnobservedTaskException

常用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) ❌ UI 事件触发 ❌ ✅ (避免 async void 风险) 长时间后台任务 ✅ (结合 CancellationToken) ✅ (需显式绑定生命周期) 高频触发(如每帧) ❌ (会产生 Task 实例) ✅ (零 GC 压力)

 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

武汉旅行社服务