csharp_thread icon indicating copy to clipboard operation
csharp_thread copied to clipboard

异步状态机的实现

Open whuanle opened this issue 3 years ago • 0 comments

namespace ConsoleApp1
{
	public class Program
	{
		static async Task Main(string[] args)
		{
			var p = new Program();

			// 这段代码被转换为状态机
			// await p.GetAsync(111);

			GGG g = new GGG()
			{
				__this = p,
				id = 111
			};
			g.__builder = AsyncTaskMethodBuilder<int>.Create();
			g.__state = -1;
			var builder = g.__builder;
			builder.Start(ref g);
			var a = g.__builder.Task;
			Console.WriteLine(a);
		}

		public async Task<int> GetAsync(int id)
		{
			Thread.Sleep(1000);
			await Task.CompletedTask;
			return 1;
		}
	}

	[CompilerGenerated]
	public struct GGG : IAsyncStateMachine
	{
		public Program __this;
		public int id;
		public AsyncTaskMethodBuilder<int> __builder;
		public int __state;
		private TaskAwaiter<int> __task1Awaiter;

		private int result;

		public void MoveNext()
		{
			try
			{
				TaskAwaiter<int> awaiter;
				if (__state != 0)
				{
					if (id == 0) throw new ArgumentNullException(nameof(id));
					awaiter = __this.GetAsync(id).GetAwaiter();

					if (!awaiter.IsCompleted)
					{
						__state = 0;
						__task1Awaiter = awaiter;
						// 没有完成的话,放到后台完成
						__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
						return;
					}
				}
				else
				{
					awaiter = __task1Awaiter;
					__task1Awaiter = default(TaskAwaiter<int>);
					__state = -1;
				}
				result = awaiter.GetResult();
			}
			catch (Exception ex)
			{
				__state = -2;
				__builder.SetException(ex);
				return;
			}

			__state = -2;
			__builder.SetResult(result);
		}

		[DebuggerHidden]
		void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
		{
			__builder.SetStateMachine(stateMachine);
		}
	}
}

whuanle avatar Aug 26 '22 03:08 whuanle