实现一个可以用 await 异步等待的 Awaiter
总结起来,要想使一个方法可被 await 等待,必须具备以下条件:
这个方法返回一个类 A 的实例,这个类 A 必须满足后面的条件。
此类 A 有一个可被访问到的 GetAwaiter 方法(扩展方法也行,这算是黑科技吗?),方法返回类 B 的实例,这个类 B 必须满足后面的条件;
此类 B 实现 INotifyCompletion 接口,且拥有 bool IsCompleted { get; } 属性、GetResult() 方法、void OnCompleted(Action continuation) 方法。
https://blog.csdn.net/WPwalter/article/details/78387736
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | using System.Runtime.CompilerServices; namespace Walterlv.Threading { /// <summary> /// 表示一个可等待对象,如果一个方法返回此类型的实例,则此方法可以使用 `await` 异步等待。 /// </summary> /// <typeparam name="TAwaiter">用于给 await 确定返回时机的 IAwaiter 的实例。</typeparam> public interface IAwaitable< out TAwaiter> where TAwaiter : IAwaiter { /// <summary> /// 获取一个可用于 await 关键字异步等待的异步等待对象。 /// 此方法会被编译器自动调用。 /// </summary> TAwaiter GetAwaiter(); } /// <summary> /// 表示一个包含返回值的可等待对象,如果一个方法返回此类型的实例,则此方法可以使用 `await` 异步等待返回值。 /// </summary> /// <typeparam name="TAwaiter">用于给 await 确定返回时机的 IAwaiter{<typeparamref name="TResult"/>} 的实例。</typeparam> /// <typeparam name="TResult">异步返回的返回值类型。</typeparam> public interface IAwaitable< out TAwaiter, out TResult> where TAwaiter : IAwaiter<TResult> { /// <summary> /// 获取一个可用于 await 关键字异步等待的异步等待对象。 /// 此方法会被编译器自动调用。 /// </summary> TAwaiter GetAwaiter(); } /// <summary> /// 用于给 await 确定异步返回的时机。 /// </summary> public interface IAwaiter : INotifyCompletion { /// <summary> /// 获取一个状态,该状态表示正在异步等待的操作已经完成(成功完成或发生了异常);此状态会被编译器自动调用。 /// 在实现中,为了达到各种效果,可以灵活应用其值:可以始终为 true,或者始终为 false。 /// </summary> bool IsCompleted { get ; } /// <summary> /// 此方法会被编译器在 await 结束时自动调用以获取返回状态(包括异常)。 /// </summary> void GetResult(); } /// <summary> /// 当执行关键代码(此代码中的错误可能给应用程序中的其他状态造成负面影响)时, /// 用于给 await 确定异步返回的时机。 /// </summary> public interface ICriticalAwaiter : IAwaiter, ICriticalNotifyCompletion { } /// <summary> /// 用于给 await 确定异步返回的时机,并获取到返回值。 /// </summary> /// <typeparam name="TResult">异步返回的返回值类型。</typeparam> public interface IAwaiter< out TResult> : INotifyCompletion { /// <summary> /// 获取一个状态,该状态表示正在异步等待的操作已经完成(成功完成或发生了异常);此状态会被编译器自动调用。 /// 在实现中,为了达到各种效果,可以灵活应用其值:可以始终为 true,或者始终为 false。 /// </summary> bool IsCompleted { get ; } /// <summary> /// 获取此异步等待操作的返回值,此方法会被编译器在 await 结束时自动调用以获取返回值(包括异常)。 /// </summary> /// <returns>异步操作的返回值。</returns> TResult GetResult(); } /// <summary> /// 当执行关键代码(此代码中的错误可能给应用程序中的其他状态造成负面影响)时, /// 用于给 await 确定异步返回的时机,并获取到返回值。 /// </summary> /// <typeparam name="TResult">异步返回的返回值类型。</typeparam> public interface ICriticalAwaiter< out TResult> : IAwaiter<TResult>, ICriticalNotifyCompletion { } } |
https://stackoverflow.com/questions/19535147/await-and-synchronizationcontext-in-a-managed-component-hosted-by-an-unmanaged-a/19555959#19555959
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class ContextAwaiter<T> : INotifyCompletion { readonly Control _control; readonly TaskAwaiter<T> _awaiter; readonly bool _alwaysAsync; public ContextAwaiter(Task<T> task, Control control, bool alwaysAsync) { _awaiter = task.GetAwaiter(); _control = control; _alwaysAsync = alwaysAsync; } public ContextAwaiter<T> GetAwaiter() { return this ; } public bool IsCompleted { get { return !_alwaysAsync && _awaiter.IsCompleted; } } public void OnCompleted(Action continuation) { if (_alwaysAsync || _control.InvokeRequired) { Action<Action> callback = (c) => _awaiter.OnCompleted(c); _control.BeginInvoke(callback, continuation); } else _awaiter.OnCompleted(continuation); } public T GetResult() { return _awaiter.GetResult(); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架