C# await 高级用法

2018-02-27 10:52:06来源:https://lindexi.gitee.io/lindexi/post/C-await-高级用法.html作者:lindexi人点击

分享

本文告诉大家 await 的高级用法,包括底层原理。


昨天看到 太子 写了一段代码,我开始觉得他修改了编译器,要不然下面的代码怎么可以编译通过


await "林德熙逗比";

需要知道,基本可以添加 await 都是可以等待的类型,如 Task 。如果一个类需要可以被等待,那么这个类必须满足以下条件


类里有一个 GetAwaiter 函数


GetAwaiter 有返回值,返回值需要继承 INotifyCompletion 并且有 bool IsCompleted { get; } , GetResult() , void OnCompleted(Action continuation) 定义


参见: 如何实现一个可以用 await 异步等待的 Awaiter - walterlv


但是上面的代码使用的是一个字符串,什么时候可以修改继承字符串?


先让我来说下 await 原理,因为知道了原理,上面的代码实现很简单。看完了本文,你就会知道如何让几乎所有类型包括 int 、string 、自定义的类都支持 await 。


如果真的不想看原理,那么请直接调到文章的最后,看到最后很快就知道如何做。


原理
使用

因为 await 需要找到一个 GetAwaiter 函数,这个函数即使是扩展方法也可以,所以其实上面的代码是这样写的


public static class KvpbamjhKsvm
{
public static HeabdsdnbKevx GetAwaiter(this string str)
{
return new HeabdsdnbKevx();
}
}
public class HeabdsdnbKevx : INotifyCompletion
{
public bool IsCompleted { get; }
public void GetResult()
{
}
/// <inheritdoc />
public void OnCompleted(Action continuation)
{
}
}

HeabdsdnbKevx 就是一个可以等待的类型


现在就可以写出下面的代码


private static void Main(string[] args)
{
DdngSiwchjux();
}
private static async void DdngSiwchjux()
{
await "林德熙逗比";
}

当然,上面的这个代码可以运行,不过不会返回什么。下面让我加上一句代码。


private static void Main(string[] args)
{
DdngSiwchjux();
}
private static async void DdngSiwchjux()
{
await "林德熙逗比";
Console.WriteLine("csdn");
}

这时可以看到, Console.WriteLine("csdn"); 不会运行,因为这时如果在 OnCompleted 函数打断点就可以看到,执行 await "林德熙逗比" 之后就进入 OnCompleted 函数。从上面的原理可以知道,这个函数传入的参数就是两个 await 或 await 和函数结束之间的代码。如果需要让 Console.WriteLine("csdn"); 运行,那么只需要在 OnCompleted 运行参数



public void OnCompleted(Action continuation)
{
continuation();
}


但是作为一个挖坑专业的大神,怎么可以就扩展 string ,下面我把 int 进行扩展


public static class KvpbamjhKsvm
{
public static HeabdsdnbKevx GetAwaiter(this int dxpbnzSce)
{
return new HeabdsdnbKevx();
}
}

随意写一个值,然后进行等待



现在我准备在 object 加一个扩展方法,所有类型都可以等待,然后把这个扩展方法的 namespace 写为 System ,这样大家就不知道这个是我写的,过了一年我就告诉大家这是 C# 的特性,所有的类都可以等待。但是这个特性需要开光才可以使用,你们直接建的项目没有开光所以没法使用这个特性。


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台