为 Unity 提供有效的无GC async/await集成
UniTask.Yield
类似于 Unity 的 yield return null
yield return null
这一帧到此暂停,下一帧再从暂停处继续执行后续的代码,常用于循环中。
等待某个条件: 在某些情况下,需要等到某个条件满足后再继续执行协程。可以使用 yield return null
在等待过程中进行循环检查。
IEnumerator WaitForCondition()
{
while (!ConditionIsMet())
{ yield return null;}
}
UniTask.Delay
(1000) 会在指定的时间间隔后继续执行任务
UniTask.DelayFrame
(20) 会在指定的帧数后继续执行任务
// 等待 someValue 发生变化
await UniTask.WaitUntilValueChanged(this, x => x.someValue);
x=> x.someValue 是 (x)=>{x.someValue;}的简写
为什么要用Func<Example, int> 类型的委托,而不是一个int值?
动态监控:
-
当我们使用
Func<Example, int>
类型的委托(例如x => x.someValue
)时,我们实际上是提供了一种方法来访问和监控对象的某个属性或字段。这样可以持续监控该属性或字段的变化。
-
每次
UniTask.WaitUntilValueChanged
需要检查值是否变化时,它都会调用这个委托来获取最新的值。
UniTask.SwitchToThreadPool
是 UniTask
库中用于切换执行上下文到线程池的一种方法。它在异步编程中非常有用,尤其是在需要将 CPU 密集型任务或长时间运行的任务从主线程(通常是 UI 线程)移到后台线程执行时。线程池(Thread Pool)是一种用于管理和重用多个线程的技术,旨在提高应用程序的性能和资源利用率。它通过维护一定数量的线程,避免频繁创建和销毁线程带来的开销,从而实现高效的任务处理。
Unitask.SuppressCancellationThrow()
当任务被取消时,会抛出 OperationCanceledException
,并在 catch 块中捕获。SuppressCancellationThrow()会返回一个布尔值,指示任务是否被取消,用于在任务取消时避免抛出 OperationCanceledException
异常。
var (isCanceled, a) = await TrainLogic.Instance.RequestTrainRoomStatus().SuppressCancellationThrow();
if (isCanceled) { Debug.Log("The task was canceled."); }
UniTask.WhenAny
:
将在任何一个任务完成(成功、失败或取消)时返回,并且不会取消其他任务。
UniTask.WhenAll
:
如果任何一个任务被取消且没有使用 SuppressCancellationThrow()
,将抛出 OperationCanceledException
。
并通过元组语义轻松获取所有结果 var (google, bing, yahoo) = await UniTask.WhenAll(task1, task2, task3); // WhenAll简写形式 var (google2, bing2, yahoo2) = await (task1, task2, task3);
注意:UniTask 有.Timeout,.TimeoutWithoutException方法,但是,如果可能,不要使用这些,请通过CancellationToken. 由于.Timeout作用在task外部,无法停止超时任务。.Timeout表示超时时忽略结果。如果您将一个CancellationToken传递给该方法,它将从任务内部执行,因此可以停止正在运行的任务。
可等待对象
在C#中,使用await
关键字可以等待的对象必须满足特定的条件。这些条件围绕着“可等待对象(awaitable objects)”的概念展开。一个可等待对象通常需要满足以下条件:
-
实现
GetAwaiter
方法: 对象必须有一个无参数的GetAwaiter
方法。这个方法是关键,因为它返回一个提供必要接口的“awaiter”对象。 -
Awaiter
对象:GetAwaiter
方法返回的对象(通常称为“awaiter”),必须实现以下方法和属性:-
IsCompleted
属性:这是一个布尔值,指示异步操作是否已完成。 -
GetResult
方法:当异步操作完成时,调用此方法来获取操作的结果。 -
OnCompleted
方法:接受一个Action
代表当异步操作完成时应该执行的回调。
-
-
类型兼容: 最常见的可等待对象类型是
Task
和Task<T>
。这些类型已经内置了必要的GetAwaiter
方法和相应的awaiter对象。但是,你也可以定义自己的可等待类型,只要它们符合上述条件。