我正在查看在ILSpy中反编译的Task.Delay(int):
// System.Threading.Tasks.Task [__DynamicallyInvokable] public static Task Delay(int millisecondsDelay) { return Task.Delay(millisecondsDelay,default(CancellationToken)); }
这个方法像await Task.Delay(5000);一样使用,而intellisense甚至说“(等待)”:
那么如何将Task.Delay(int)标记为异步(public static async Task Delay(int millisecondsDelay))?
解决方法
什么是可以接受的任务Task.Delay返回.返回任务/任务的每个方法< TResult>是等待的. async只是一个实现细节,允许您在该方法中使用await以及它生成的整个状态机.
更一般地说,可以等待具有返回具有IsCompleted,OnCompleted和GetResult的东西的GetAwaiter方法(extension methods count as well)的所有东西.
例如,Task.Yield返回的YieldAwaitable不是Task,如下所示:
public struct YieldAwaiter : ICriticalNotifyCompletion,INotifyCompletion { public void OnCompleted(Action continuation); public void UnsafeOnCompleted(Action continuation); public void GetResult(); public bool IsCompleted { get; } }
*这里的UnsafeOnCompleted只是一个优化,没有它就等待.
重要的是要注意,在这种情况下编译器(与其他情况相同,如foreach的GetEnumerator)不期望接口或基类.它基本上使用duck typing(即“如果它像鸭子一样行走……”)并且只是寻找一个GetAwaiter方法,它返回任何东西(无论什么类型或接口,或者它是一个类或一个结构)还有另一个3个成员(IsCompleted,OnCompleted和GetResult)
例如,这就是你可以等待“bar”编译的方法(它当然会在运行时失败):
public static Awaiter GetAwaiter(this string s) { throw new NotImplementedException(); } public abstract class Awaiter : INotifyCompletion { public abstract bool IsCompleted { get; } public abstract void GetResult(); public abstract void OnCompleted(Action continuation); }
总而言之,您不需要异步返回等待,而且.Net框架中的大多数任务返回方法不使用它并显式返回任务.