ToB企服应用市场:ToB评测及商务社交产业平台

标题: .NET6中的await原理浅析 [打印本页]

作者: 汕尾海湾    时间: 2023-12-20 21:17
标题: .NET6中的await原理浅析
前言

看过不少关于 await 的原理的文章,也知道背后是编译器给转成了状态机实现的,但是具体是怎么完成的,回调又是如何衔接的,一直都没有搞清楚,这次下定决心把源码自己跑了下,终于豁然开朗了
本文的演示代码基于 VS2022 + .NET 6
示例
  1. public class Program
  2. {
  3.     static int Work()
  4.     {
  5.         Console.WriteLine("In Task.Run");
  6.         return 1;
  7.     }
  8.     static async Task TestAsync()
  9.     {
  10.         Console.WriteLine("Before Task.Run");
  11.         await Task.Run(Work);
  12.         Console.WriteLine("After Task.Run");
  13.     }
  14.     static void Main()
  15.     {
  16.         _ = TestAsync();
  17.         Console.WriteLine("End");
  18.         Console.ReadKey();
  19.     }
  20. }
复制代码
  1. class Program
  2. {
  3.     static int Work()
  4.     {
  5.         Console.WriteLine("In Task.Run");
  6.         return 1;
  7.     }
  8.     static Task TestAsync()
  9.     {
  10.         var stateMachine = new StateMachine()
  11.         {
  12.             _builder = AsyncTaskMethodBuilder.Create(),
  13.             _state = -1
  14.         };
  15.         stateMachine._builder.Start(ref stateMachine);
  16.         return stateMachine._builder.Task;
  17.     }
  18.     static void Main()
  19.     {
  20.         _ = TestAsync();
  21.         Console.WriteLine("End");
  22.         Console.ReadKey();
  23.     }
  24.     class StateMachine : IAsyncStateMachine
  25.     {
  26.         public int _state;
  27.         public AsyncTaskMethodBuilder _builder;
  28.         private TaskAwaiter<int> _awaiter;
  29.         void IAsyncStateMachine.MoveNext()
  30.         {
  31.             int num = _state;
  32.             try
  33.             {
  34.                 TaskAwaiter<int> awaiter;
  35.                 if (num != 0)
  36.                 {
  37.                     Console.WriteLine("Before Task.Run");
  38.                     awaiter = Task.Run(Work).GetAwaiter();
  39.                     if (!awaiter.IsCompleted)
  40.                     {
  41.                         _state = 0;
  42.                         _awaiter = awaiter;
  43.                         StateMachine stateMachine = this;
  44.                         _builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
  45.                         return;
  46.                     }
  47.                 }
  48.                 else
  49.                 {
  50.                     awaiter = _awaiter;
  51.                     _awaiter = default;
  52.                     _state = -1;
  53.                 }
  54.                 awaiter.GetResult();
  55.                 Console.WriteLine("After Task.Run");
  56.             }
  57.             catch (Exception exception)
  58.             {
  59.                 _state = -2;
  60.                 _builder.SetException(exception);
  61.                 return;
  62.             }
  63.             _state = -2;
  64.             _builder.SetResult();
  65.         }
  66.         void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { }
  67.     }
  68. }
复制代码
状态机实现

线程池实现

  1. static void DispatchWorkItem(object workItem, Thread currentThread)
  2. {
  3.     Task task = workItem as Task;
  4.     if (task != null)
  5.     {
  6.         task.ExecuteFromThreadPool(currentThread);
  7.         return;
  8.     }
  9.     Unsafe.As<IThreadPoolWorkItem>(workItem).Execute();
  10. }
  11. virtual void ExecuteFromThreadPool(Thread threadPoolThread)
  12. {
  13.     this.ExecuteEntryUnsafe(threadPoolThread);
  14. }
复制代码
总结

备注


参考链接

概述 .NET 6 ThreadPool 实现: https://www.cnblogs.com/eventhorizon/p/15316955.html
.NET Task 揭秘(2):Task 的回调执行与 await: https://www.cnblogs.com/eventhorizon/p/15912383.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4