## awaitable表达式要求 为了与 `await` 操作符保持兼容,类型应当遵守在C#规则说明中规定的一些要求。 我安装的是VS2017,其路径为: *C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC#\Specifications\1033 └ [CSharp Language Specification.docx](/Uploads/userfiles/e671fced-86e2-4d56-a20a-d79aab766aa7/files/2017/08/CSharp Language Specification.docx)* ------ ### 7.7.7.1 Awaitable expressions > The task of an await expression is required to be awaitable. An expression t is awaitable if one of the following holds: > Await表达式的任务被要求是awaitable。如果一个表达式t满足下面任意一条则认为是awaitalbe的: > - t is of compile time type dynamic > t是动态编译时的类型 > - t has an accessible instance or extension method called GetAwaiter with no parameters and no type parameters, and a return type A for which all of the following hold: > t有一个名为GetAwaiter的可访问的实例或扩展方法。该方法没有参数和类型参数,并且返回值类型A满足以下所有条件 > - A implements the interface System.Runtime.CompilerServices.INotifyCompletion (hereafter known as INotifyCompletion for brevity) > A实现了 System.Runtime.CompilerServices.INotifyCompletion 接口(为简单起见,以后简称为 INotifyCompletion) > - A has an accessible, readable instance property IsCompleted of type bool > A有一个可访问的、可读的类型为bool的实例属性IsCompleted。 > - A has an accessible instance method GetResult with no parameters and no type parameters > A有一个名为GetResult的可访问的实例方法,该方法没有任何参数和类型参数。 > > The purpose of the GetAwaiter method is to obtain an awaiter for the task. The type A is called the awaiter type for the await expression. > The purpose of the IsCompleted property is to determine if the task is already complete. If so, there is no need to suspend evaluation. > The purpose of the INotifyCompletion.OnCompleted method is to sign up a “continuation” to the task; i.e. a delegate (of type System.Action) that will be invoked once the task is complete. > The purpose of the GetResult method is to obtain the outcome of the task once it is complete. This outcome may be successful completion, possibly with a result value, or it may be an exception which is thrown by the GetResult method. ------ ## 示例代码 ``` /// <summary> /// 自定义awaitable类型 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Task t = AsynchronousProcessing(); t.Wait(); Console.ReadLine(); } static async Task AsynchronousProcessing() { var sync = new CustomAwaitable(true); string result = await sync; // Completed synchronously Console.WriteLine(result); var async = new CustomAwaitable(false); result = await async; // Task is running on a thread id 3. Is thread pool thread: True Console.WriteLine(result); } /// <summary> /// 类型t /// </summary> class CustomAwaitable { private readonly bool _completeSynchronously; public CustomAwaitable(bool completeSynchronously) { _completeSynchronously = completeSynchronously; } /// <summary> /// t有一个名为GetAwaiter的可访问的实例或扩展方法 /// </summary> /// <returns>类型A</returns> public CustomAwaiter GetAwaiter() { return new CustomAwaiter(_completeSynchronously); } } /// <summary> /// 类型A 实现了 System.Runtime.CompilerServices.INotifyCompletion 接口 /// </summary> class CustomAwaiter : INotifyCompletion { private string _result = "Completed synchronously"; private readonly bool _completeSynchronously; /// <summary> /// A有一个可访问的、可读的类型为bool的实例属性IsCompleted /// 如果IsCompleted属性返回true,则只需同步调用GetResult方法 /// </summary> public bool IsCompleted => _completeSynchronously; public CustomAwaiter(bool completeSynchronously) { _completeSynchronously = completeSynchronously; } /// <summary> /// A有一个名为GetResult的可访问的实例方法,该方法没有任何参数和类型参数。 /// </summary> /// <returns></returns> public string GetResult() { return _result; } public void OnCompleted(Action continuation) { ThreadPool.QueueUserWorkItem(state => { Thread.Sleep(TimeSpan.FromSeconds(1)); _result = GetInfo(); continuation?.Invoke(); }); } private string GetInfo() { return $"Task is running on a thread id {Thread.CurrentThread.ManagedThreadId}. " + $"Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}"; } } ``` 运行结果: ``` Completed synchronously Task is running on a thread id 3. Is thread pool thread: True ``` ## notes *该实现只适用于教学目的。当你编写异步函数时,最自然的方式好还是使用标准的Task类型。* Loading... 版权声明:本文为博主「佳佳」的原创文章,遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://www.liujiajia.me/blog/details/csharp-multi-threading-05-csharp6-08-customize-awaitable 提交