c# – 如果没有标记为异步,Task.Delay是如何等待的?

前端之家收集整理的这篇文章主要介绍了c# – 如果没有标记为异步,Task.Delay是如何等待的?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在查看在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框架中的大多数任务返回方法不使用它并显式返回任务.

原文链接:https://www.f2er.com/csharp/97981.html

猜你在找的C#相关文章