我在几篇文章中都说到了在 .NET 中自己实现 Awaiter 情况。async / await 写异步代码用起来真的很爽,就像写同步一样。然而实现 Awaiter 没有现成的接口,它需要你按照编译器的要求为你的类型添加一些具有特定名称的属性和方法。然而没有接口的帮助,我们编写起来就很难获得工具(如 ReSharper)自动生成代码的支持。

本文将分享我提取的自己实现 Awaiter 的接口。你只需要实现这些接口当中的 2 个,就能正确实现一个 Awaitable 和 Awaiter。


接口代码

你可以在 GitHub 上找到这段代码:https://github.com/walterlv/sharing-demo/blob/master/src/Walterlv.Core/Threading/AwaiterInterfaces.cs

public interface IAwaitable<out TAwaiter> where TAwaiter : IAwaiter
{
TAwaiter GetAwaiter();
} public interface IAwaitable<out TAwaiter, out TResult> where TAwaiter : IAwaiter<TResult>
{
TAwaiter GetAwaiter();
} public interface IAwaiter : INotifyCompletion
{
bool IsCompleted { get; } void GetResult();
} public interface ICriticalAwaiter : IAwaiter, ICriticalNotifyCompletion
{
} public interface IAwaiter<out TResult> : INotifyCompletion
{
bool IsCompleted { get; } TResult GetResult();
} public interface ICriticalAwaiter<out TResult> : IAwaiter<TResult>, ICriticalNotifyCompletion
{
}

接口实现

在 ReSharper 工具的帮助下,你可以在继承接口之后快速编写出实现代码来:


▲ 使用 ReSharper 快速实现 Awaiter


▲ 使用 ReSharper 快速实现 Awaitable

于是我们可以迅速得到一对可以编译通过的 Awaitable 和 Awaiter:

public sealed class Awaiter : IAwaiter<string>
{
public void OnCompleted(Action continuation)
{
throw new NotImplementedException();
} public bool IsCompleted { get; } public string GetResult()
{
throw new NotImplementedException();
}
} public sealed class Awaitable : IAwaitable<Awaiter, string>
{
public Awaiter GetAwaiter()
{
throw new NotImplementedException();
}
}

当然,你也可以在一个类里面实现这两个接口:

public sealed class Awaiter : IAwaiter<string>, IAwaitable<Awaiter, string>
{
public void OnCompleted(Action continuation)
{
throw new NotImplementedException();
} public bool IsCompleted { get; } public string GetResult()
{
throw new NotImplementedException();
} public Awaiter GetAwaiter()
{
return this;
}
}

实现业务需求

我有另外两篇文章在实现真正可用的 Awaiter:

更多 Awaiter 系列文章

入门篇:

实战篇:

定义一组抽象的 Awaiter 的实现接口,你下次写自己的 await 可等待对象时将更加方便的更多相关文章

  1. java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0

    java 继承使用关键字extends   继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...

  2. 如何实现一个可以用 await 异步等待的 Awaiter

    .NET 和 C# 共同给我们带来的 async/await 异步编程模型(TAP)用起来真的很爽.为了实现异步等待,我们只需要在一切能够能够异步等待的方法前面加上 await 即可.能够异步等待的最 ...

  3. stm32的swd接口的烧写协议是否公开的呢?

    stm32的swd接口的烧写协议是否公开的呢? 需要用一台好的示波器来抓才能有足够的存储深度,保证你能够过滤掉那个该死的50clock. 按照Arm的手册,每次转换发送方都需要一个TNR---但是我观 ...

  4. 集合框架的类和接口均在java.util包中。 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。

    集合框架的类和接口均在java.util包中. 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换.

  5. Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法EDIT Object.defineProperty(obj, ...

  6. QCache<key,T> 就定义了一个缓存,其类似于map,好处是QCache自动获得被插入对象的所有权,控制所有对象的costs总和(自动管理对象的生存时间。正经数据是不会用到它的,辅助控制才有可能用到它)

    在软件开发中,我们经常需要在内存中存储一些临时数据用于后续相关计算.我们一般把这些数据存储到某个数组里,或者STL中的某个合适的容器中.其实,在Qt中直接为我们提供了一个QCache类专用于这种需求. ...

  7. 实现一个可以用 await 异步等待的 Awaiter

    总结起来,要想使一个方法可被 await 等待,必须具备以下条件: 这个方法返回一个类 A 的实例,这个类 A 必须满足后面的条件.此类 A 有一个可被访问到的 GetAwaiter 方法(扩展方法也 ...

  8. (1)定义一个接口CanFly,描述会飞的方法public void fly(); (2)分别定义类飞机和鸟,实现CanFly接口。 (3)定义一个测试类,测试飞机和鸟,在main方法中创建飞机对象和鸟对象, 再定义一个makeFly()方法,其中让会飞的事物飞。并在main方法中调用该方法, 让飞机和鸟起飞。

    package b; public interface CanFly { public void fly(); } package b; public class FeiJi implements C ...

  9. 没想到吧,Java开发 API接口可以不用写 Controller了

    本文案例收录在 https://github.com/chengxy-nds/Springboot-Notebook 大家好,我是小富~ 今天介绍我正在用的一款高效敏捷开发工具magic-api,顺便 ...

随机推荐

  1. Unity游戏中关于伤害范围的计算

    1.纯数学计算 范围计算 + 方向计算: 先将不在伤害范围的敌人排除掉,再计算处于伤害范围并且角度正确的敌人. 以上的计算是以人物的中心来计算的, 所以这中方式就有些局限性了,比如:一个四足怪物,只有 ...

  2. Android 使用SQLite

    SQLite简介 Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLit ...

  3. 流氓 2345.com的新动态及解决方法

    安装了[电脑公司]的Win7_SP1之后, IE的主页被绑架. 症状是先转到 IE959.com,然后自动跳转到 www.2345.com 网上当然有很多例子了,可是都没有效果. 1. 更改IE设置没 ...

  4. 雷林鹏分享:Ruby 命令行选项

    Ruby 命令行选项 Ruby 一般是从命令行运行,方式如下: $ ruby [ options ] [.] [ programfile ] [ arguments ... ] 解释器可以通过下列选项 ...

  5. Jersey 2.x 分支 Java SE 兼容性

    直到 Jersey 2.6 版本,Jersey 将会兼容 Java SE 6.这个情况将会在在 Jersey 2.7 的版本有所改变. 直到 Jersey 版本 2.25x, 所有的 Jersey 的 ...

  6. Confluence 6 使用 LDAP 授权连接到 Confluence 内部目录

    希望连接一个内部目录但是使用 LDAP 检查登录授权: 在屏幕的右上角单击 控制台按钮 ,然后选择 General Configuration 链接. 单击左侧面板上面的 用户目录(User Dire ...

  7. Ubuntu 18.04 install JDK8.201

    sudo add-apt-repository ppa:webupd8team/java Press Enter to continue. sudo apt update sudo apt insta ...

  8. python-day47--pymysql模块

    一.安装导入 #安装 pip3 install pymysql 二.使用 1 .基本使用 import pymysql # 链接,拿到游标 conn=pymysql.connect(host='loc ...

  9. Netty高性能编程备忘录(下)

    估计很快就要被拍砖然后修改,因此转载请保持原文链接,否则视为侵权... http://calvin1978.blogcn.com/articles/netty-performance.html 前文再 ...

  10. POJ 1860 Bellman-Ford算法

    转载链接:http://blog.csdn.net/lyy289065406/article/details/6645778 提示:关键在于反向利用Bellman-Ford算法 题目大意 有多种汇币, ...