首页 > 其他分享 >.net core中异步async await

.net core中异步async await

时间:2024-12-16 19:20:58浏览次数:4  
标签:core stateMachine await 状态机 state awaiter async net ref

基本原理

async ,await是C#语言中用于简化异步操作的语法糖,实际会由编译器将代码翻译生成状态机
执行异步操作。
状态机 是一种数学模型,用于描述一个系统在不同状态之间的转换行为。它由一组状态和一组转换组成,在特定的输入条件下,系统从一个状态转换到另一个状态。
例如如下的异步方法

public async Task<string> FetchDataAsync(string url)  
{  
	using (HttpClient client = new HttpClient())  
	{  
		string content = await client.GetStringAsync(url);
		Console.WriteLine("执行成功!");
		return content;  
	}  
}

当编译器遇到Async符号时,会将整个方法,转换为状态机,反编译整理简化后相关代码如下:

public Task<string> FetchDataAsync(string url)  
{  
	var stateMachine = new FetchDataStateMachine();  
	stateMachine.url = url;  
	stateMachine.builder = AsyncTaskMethodBuilder<string>.Create();  
	stateMachine.state = -1;  
	stateMachine.builder.Start(ref stateMachine);  
	return stateMachine.builder.Task;  
}  
  
private struct FetchDataStateMachine : IAsyncStateMachine  
{  
	public int state;  
	public AsyncTaskMethodBuilder<string> builder;  
	public string url;  
	private HttpClient client;  
	private TaskAwaiter<string> awaiter;  
	private string result;  
  
	public void MoveNext()  
	{  
		try  
		{  
			if (state!=0)  
			{  
				client = new HttpClient();  
				var task = client.GetStringAsync(url);  
				awaiter = task.GetAwaiter();  
				//判断任务是否已经执行完毕,如果执行完,直接就返回结果了
				if (!awaiter.IsCompleted)  
				{  
					state = 0;
					//注册回调,当task执行完后再执行MoveNext方法
					builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);  
					return;  
				}  
			}  
			//任务执行完毕后设置state
			if (state == 0)  
			{  
				state = -1;   
			}  
  		    result = awaiter.GetResult();  
  		    //执行await 以后的代码
  		    Console.WriteLine("执行成功!"); 
		}  
		catch (Exception ex)  
		{  
			state = -2;  
			builder.SetException(ex);  
		}  
		finally
		{
			if(num<0&&client!=null)
			{
				client.Dispose();
			}
		}
		state=-2;
		builder.SetResult(result);  
	}  
  
	public void SetStateMachine(IAsyncStateMachine stateMachine)  
	{  
		builder.SetStateMachine(stateMachine);  
	}  
}

编译器会生成一个FetchDataStateMachine 状态机类, 继承自IAsyncStateMachine 接口,将异步方法中的相关变量放在状态机字段中;状态机中的一个重要方法是MoveNext(),用于处理状态变化时的对应操作。
翻译后的代码主要执行以下两个操作

  • 初始化状态机 , 新增状态机,并初始化相关字段,设置初始状态state为-1,启动状态机。
  • 执行MoveNext()方法,state!=0,执行任务,如果任务耗时短直接可以获取结果,则直接返回结果;耗时长则设置state字段为0,并通过AwaitUnsafeOnCompleted注册任务完成后的回调,当任务完成后会再执行MoveNext()方法,此时state 字段为0,方法从awaiter中获取执行结果,并执行原方法中await以后的后续代码并返回。
    AsyncTaskMethodBuilder<T>中AwaitUnsafeOnCompleted方法
   internal static void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
            ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref Task<TResult>? taskField)
            where TAwaiter : ICriticalNotifyCompletion
            where TStateMachine : IAsyncStateMachine
        {
            IAsyncStateMachineBox box = GetStateMachineBox(ref stateMachine, ref taskField);
            AwaitUnsafeOnCompleted(ref awaiter, box);
        }



   internal static void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
            ref TAwaiter awaiter, ref TStateMachine stateMachine, [NotNull] ref Task<TResult>? taskField)
            where TAwaiter : ICriticalNotifyCompletion
            where TStateMachine : IAsyncStateMachine
        {
            IAsyncStateMachineBox box = GetStateMachineBox(ref stateMachine, ref taskField);
            AwaitUnsafeOnCompleted(ref awaiter, box);
        }




        internal static void AwaitUnsafeOnCompleted<TAwaiter>(
            ref TAwaiter awaiter, IAsyncStateMachineBox box)
            where TAwaiter : ICriticalNotifyCompletion
        {
            if ((null != (object?)default(TAwaiter)) && (awaiter is ITaskAwaiter))
            {
                ref TaskAwaiter ta = ref Unsafe.As<TAwaiter, TaskAwaiter>(ref awaiter); // relies on TaskAwaiter/TaskAwaiter<T> having the same layout
                TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, continueOnCapturedContext: true);
            }
            else if ((null != (object?)default(TAwaiter)) && (awaiter is IConfiguredTaskAwaiter))
            {
                ref ConfiguredTaskAwaitable.ConfiguredTaskAwaiter ta = ref Unsafe.As<TAwaiter, ConfiguredTaskAwaitable.ConfiguredTaskAwaiter>(ref awaiter);
                TaskAwaiter.UnsafeOnCompletedInternal(ta.m_task, box, (ta.m_options & ConfigureAwaitOptions.ContinueOnCapturedContext) != 0);
            }
            else if ((null != (object?)default(TAwaiter)) && (awaiter is IStateMachineBoxAwareAwaiter))
            {
                try
                {
		        ((IStateMachineBoxAwareAwaiter)awaiter).AwaitUnsafeOnCompleted(box);
                }
                catch (Exception e)
                {
                    Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
                }
            }
            else
            {
                // The awaiter isn't specially known. Fall back to doing a normal await.
                try
                {
                    awaiter.UnsafeOnCompleted(box.MoveNextAction);
                }
                catch (Exception e)
                {
                    Threading.Tasks.Task.ThrowAsync(e, targetContext: null);
                }
            }
        }

AwaitUnsafeOnCompleted()方法根据awaiter 的类型注册对应的OnCompleted任务完成后的回调方法,也就是MoveNext()方法,其中状态机被封装在IAsyncStateMachineBox类型的box中。
整个状态机的执行流程如下图

参考内容

Async/Await deep dive: how dotnet manage asynchronous code
Async/Await在 C#语言中是如何工作的
深入理解async 和 await 理解
.NET 6.0 中的 await 原理浅析
async、await原理揭秘
NetCore高级系列文章04---async、await原理揭秘
.NET Task 揭秘(3)async 与 AsyncMethodBuilder - 黑洞视界 - 博客园
进阶篇:以IL为剑,直指async/await - Dev_Eric - 博客园

标签:core,stateMachine,await,状态机,state,awaiter,async,net,ref
From: https://www.cnblogs.com/dao-/p/18610982

相关文章

  • 云原生周刊:Kubernetes v1.32 正式发布
    云原生周刊:Kubernetesv1.32正式发布开源项目推荐HelmperHelmper简化了将HelmCharts导入OCI(开放容器倡议)注册表的过程,并支持可选的漏洞修复功能。它确保您的HelmCharts不仅安全存储,还能及时应用最新的安全修复。该工具完全兼容OCI标准,能够方便地与OCI注册表集成,自动......
  • 开源网关(Netflix Zuul&Spring Cloud Gateway,Kong&Tyk)对比
    Zuul(NetflixZuul)与SpringCloudGateway对比性能方面Zuul:Zuul1.x是基于Servlet的同步阻塞模型,在处理高并发请求时性能相对较弱。每个请求都会占用一个线程,当并发量较大时,线程资源可能会成为瓶颈。不过,Zuul2.x版本在性能上有所改进,采用了异步非阻塞模型,能够更好地处理高并......
  • 你不知道的 async、await 魔鬼细节
    0、前言关于promise、async/await的使用相信很多小伙伴都比较熟悉了,但是提到事件循环机制输出结果类似的题目,你敢说都会?asyncfunctionasync1(){awaitnewPromise((resolve,reject)=>{resolve()})console.log('A')}async1()newPromi......
  • UI框架DevExpress XAF v24.2新功能预览 - .NET Core / .NET增强
    DevExpressXAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。DevExpressXAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。在上文中(点击这里回顾>>),我们为大家介绍了DevExpressXAFv24.2......
  • .Net Core 特性 获取Cookie,未登录跳转登录界面
    特性:usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.AspNetCore.Mvc.Filters;usingNewtonsoft.Json.Linq;usingSystem.Net;usingWaterCloud.Entity.SystemManage;namespaceOPAC.App_Start.Handler{publicclassAdminAuthorizeAttribute:TypeFilterAttr......
  • RepoDB:一个介于Dapper、EFCore之间.Net的ORM库
    推荐一个介轻量ORM和全功能ORM的开源项目。01项目简介RepoDB提供了基本操作所需的方法,同时也提供了一些高级功能,如第二层缓存、跟踪、仓储、属性处理器和批量/大量操作。支持的数据库,包括SqlServer、SQLite、MySql和PostgreSql等。02关键特性1、基础操作支持RepoDB提供了......
  • ASP.NET IdentityServer4
    publicclassConfig{///<summary>///微服务API资源///</summary>///<returns></returns>publicstaticIEnumerable<ApiResource>GetApiResources(){returnne......
  • .NET8升级.NET9,CodeFirst模式迁移Add-Migration执行Update-DataBase报错
    在做netcore开发时,如果net8一直是正常的,只升级了一下框架net9,在使用EntityFrameworkCore的CodeFirst模式进行迁移时,执行Add-Migration后尝试使用Update-DataBase时出现了如下错误。Unhandledexception.System.InvalidOperationException:Anerrorwasgeneratedforwarni......
  • .Net_比对Json文件是否一致
    简介该方法用于比较两个Json文件是否完全一致,仅考虑内容若两个文件中的内容只是顺序不一致,内容是一样的,那么也代表这两个文件是相等的实现代码调用usingCompareJsonFiles;Console.WriteLine("=================输入信息===================");Console.WriteLi......
  • 深度Q网络(Deep Q-Network, DQN)详解
    ✅作者简介:2022年博客新星第八。热爱国学的Java后端开发者,修心和技术同步精进。......