Token的使用方法 UniTaskCompletionSource UniTaskCompletionSource<T>
可被实例化传入泛型,泛型可作为结果通过Task属性返回。如
1 2 3 4 5 6 7 8 9 public static UniTask <T > LoadAssetsAsync <T >(string path ) { var utcs = new UniTaskCompletionSource<T>(); LoadAsync<T>(path,(res)=>{ utcs.TrySetResult(res) return utcs.Task; }) return utcs.Task; }
这种utcs最好的应用场景就是封装原有的 回调式的异步方法,使之能够await,并且使用Unitask生态带来的Unitask操作。这个token是可以复用的
CancellationTokenSource cancellation可以用于任务的取消
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var firstCancelToken = new CancellationTokenSource()var secondCancelToken = new CancellationTokenSource()var linkedCancelToken = CancellationTokenSource.CreateLinkedTokenSource(firstCancelToken,secondCancelToken) UnityWebRequest.Get(url).SendWebRequest().WithCancellation(secondCancelToken.Token) try { await LoadAssetAsync() }catch (OperationCanceledException e){ }var (cancelled,_) = await LoadAssetAsync().SuppressCancellationThrow();if (cancelled){...} firstCancelToken.Cancel(); firstCancelToken.Despose(); firstCancelToken = new CanclelationTokenSource()
cts.CancelAfterSlim(TimeSpan.FromSeconds(5f))
5s后触发取消操作
延时操作 Unitask.Delay(TimeSpan.FromSeconds(0.1f))
等待0.1sUnitask.Delay(TimeSpan.FromSeconds(0.1f,true))
忽略timescaleUnitask.DelayFrame(5)
延时5帧Unitask.NextFrame()
下一帧的Update之后执行 yield return nullUnitask.WaitEndofFrame()
这一帧结束下一帧开始之前执行 相当于 yield return endofFrameUnitask.Yeild(timeloop)
这个可以自定义playerloop之后执行 这一个效率最高
UniTask等待条件触发 UniTask.WaitUntil(()=>somethingOk);
等待值为TrueUniTask.WaitUntilValueChanged();
等待值改变
多个Unitask操作 WhenAll()
等待全部完成WhenAny()
等待一个完成
同步方法中执行异步方法 SomeAsyncMethod().Forget()
使用Unitask执行线程 1 2 3 4 5 6 7 await UniTask.RunOnThreadPool(()=>{})await UniTask.SwitchToMainThread();await UniTask.SwitchToThreadPool();await File.ReadAllTextAsync(filename)await UniTask.Yield(PlayerLoopTiming.Update)
Unitask的 IUniTaskAsyncEnumerable 对象的用法 很多UI的对象可以转化为这类对象,例如 var asyncEnumerable = Button.OnClickAsAsyncEnumerable(); 这会使得每一次点击都会向 asyncEnumerable中添加一次内容。使用场景可以如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var asyncEnumerable = Button.OnClickAsAsyncEnumerable()await asyncEnumerable.Take(3 ).ForEachAsync((_,index)=>{ if (index==0 ) if (index==2 ) },token) await asyncEnumerable.ForEachAwaitAsync(async (_)=>{ await UniTask.Delay(TimeSpan.FromSeconds(2f ),cancellationToken: token) })
实质上异步可迭代器可以将其范围扩大,无论是按钮还是自定义触发的事件都可以使用它。可以很方便的实现诸如上面的对具体触发次数进行判断,或者判断双击,对点击进行限制等等操作。所以除了按钮事件,Unity上还有很多事件例如碰撞等,都可以转化为碰撞可迭代器。
UniTask的异步流编写方式 1 2 3 4 5 6 7 8 9 10 11 12 private AsyncReactiveProperty<int > currentHp = new AsyncReactiveProperty<int >(100 );public Text ShowHpText; currentHp.Subscribe(OnHpChange) currentHp.WithoutCurrent().ForEachAsync((_,index)=>{}) currentHp.FirstAsync((value )=>{}) currentHp.BindTo(ShowHpText);