当前位置: 首页> 汽车> 车展 > 英文作文_东莞市企慕网络科技有限公司_海南百度推广总代理商_各种网站

英文作文_东莞市企慕网络科技有限公司_海南百度推广总代理商_各种网站

时间:2025/7/11 0:19:26来源:https://blog.csdn.net/kfashfasf/article/details/144737687 浏览次数: 0次
英文作文_东莞市企慕网络科技有限公司_海南百度推广总代理商_各种网站

在C#中,async 和 await 关键字用于编写异步代码。本文将详细介绍 await 的实现原理,包括状态机的生成、回调函数的注册和触发等关键步骤。

1. 异步方法的基本概念

在C#中,async 关键字标记一个方法为异步方法,而 await 关键字用于等待一个异步操作完成。异步方法可以提高程序的响应性和性能,特别是在处理I/O操作和网络请求时。

2. 示例异步方法

我们以一个简单的异步方法为例,来详细解释 await 的实现原理。

public class Example
{public async Task<int> CalculateAsync(){int a = await Task.Run(() => 10);int b = await Task.Run(() => 20);return a + b;}
}

3. 编译器生成的状态机

编译器会为每个异步方法生成一个状态机。状态机是一个结构体,包含了异步方法的所有局部变量和状态信息。

编译器生成的状态机类

public class Example
{public Task<int> CalculateAsync(){<CalculateAsync>d__0 stateMachine = new <CalculateAsync>d__0();stateMachine.<>4__this = this;stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();stateMachine.<>1__state = -1;stateMachine.<>t__builder.Start(ref stateMachine);return stateMachine.<>t__builder.Task;}[StructLayout(LayoutKind.Auto)][AsyncMethodBuilder(typeof(AsyncTaskMethodBuilder<int>))]private struct <CalculateAsync>d__0 : IAsyncStateMachine{public int <>1__state;public AsyncTaskMethodBuilder<int> <>t__builder;public Example <>4__this;public int <a>5__1;public TaskAwaiter<int> <>u__1;private void MoveNext(){int num = <>1__state;try{TaskAwaiter<int> awaiter;switch (num){case 0:goto TR_0000;case 1:<>1__state = -1;awaiter = <>u__1;<>u__1 = default(TaskAwaiter<int>);goto TR_0001;case 2:<>1__state = -1;break;default:<>1__state = 0;awaiter = Task.Run<int>(() => 10).GetAwaiter();if (!awaiter.IsCompleted){num = (<>1__state = 0);<>u__1 = awaiter;<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;}goto TR_0000;}TR_0000:<a>5__1 = awaiter.GetResult();awaiter = Task.Run<int>(() => 20).GetAwaiter();if (!awaiter.IsCompleted){num = (<>1__state = 1);<>u__1 = awaiter;<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;}TR_0001:int b = awaiter.GetResult();int result = <a>5__1 + b;<>1__state = -2;<>t__builder.SetResult(result);}catch (Exception exception){<>1__state = -2;<>t__builder.SetException(exception);}}[DebuggerHidden]private void SetStateMachine(IAsyncStateMachine stateMachine){}}
}

4. 实现流程详解

初始化状态机

在 CalculateAsync 方法中,创建状态机实例 <CalculateAsync>d__0

<CalculateAsync>d__0 stateMachine = new <CalculateAsync>d__0();
stateMachine.<>4__this = this;
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>1__state = -1;

  • <>4__this:指向当前实例,即 Example 类的实例。

  • <>t__builder:创建 AsyncTaskMethodBuilder<int> 实例,用于管理任务的生命周期。

  • <>1__state:初始化状态为 -1,表示方法尚未开始执行。

开始执行

调用 Start 方法开始执行异步方法。Start 方法会调用状态机的 MoveNext 方法。

stateMachine.<>t__builder.Start(ref stateMachine);

执行方法体

在 MoveNext 方法中,根据当前状态 <>1__state 执行相应的代码。

private void MoveNext()
{int num = <>1__state;try{TaskAwaiter<int> awaiter;switch (num){// 处理不同的状态}}catch (Exception exception){<>1__state = -2;<>t__builder.SetException(exception);}
}

遇到 await

遇到第一个 await 关键字时,调用 Task.Run(() => 10).GetAwaiter() 获取 Awaiter 对象。

awaiter = Task.Run<int>(() => 10).GetAwaiter();

  • 检查 awaiter.IsCompleted,如果任务已经完成,直接调用 awaiter.GetResult() 获取结果。

  • 如果任务未完成,记录当前状态 <>1__state,保存 awaiter 对象,并调用 <>t__builder.AwaitUnsafeOnCompleted 注册回调。

if (!awaiter.IsCompleted)
{num = (<>1__state = 0);<>u__1 = awaiter;<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;
}

注册回调

AwaitUnsafeOnCompleted 方法会注册一个回调,当任务完成时,回调会被触发。

public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)where TAwaiter : ICriticalNotifyCompletionwhere TStateMachine : IAsyncStateMachine
{awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
}

  • awaiter.UnsafeOnCompleted 方法注册一个回调函数,该回调函数会在任务完成时被触发。

  • stateMachine.MoveNext 是一个委托,指向状态机的 MoveNext 方法。

任务完成

当任务完成时,回调会被触发,重新调用 MoveNext 方法,恢复异步方法的执行。

public void OnCompleted(Action continuation)
{task.ContinueWith(_ => continuation(), TaskScheduler.Default);
}

继续执行

从上次暂停的地方继续执行方法体。

TR_0000:
<a>5__1 = awaiter.GetResult();
awaiter = Task.Run<int>(() => 20).GetAwaiter();
if (!awaiter.IsCompleted)
{num = (<>1__state = 1);<>u__1 = awaiter;<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;
}

  • 遇到第二个 await 关键字时,重复上述步骤。

方法完成

当所有异步操作完成并计算出结果后,设置状态 <>1__state 为 -2,表示方法已经完成。

int b = awaiter.GetResult();
int result = <a>5__1 + b;
<>1__state = -2;
<>t__builder.SetResult(result);

  • 调用 <>t__builder.SetResult 设置任务的结果。

  • 如果在执行过程中抛出异常,捕获异常并调用 <>t__builder.SetException 设置任务的异常。

catch (Exception exception)
{<>1__state = -2;<>t__builder.SetException(exception);
}

5. 深入理解 AsyncTaskMethodBuilder

AsyncTaskMethodBuilder 是一个辅助类,用于构建和管理异步方法的任务。它提供了以下方法:

  • Create:创建一个新的 AsyncTaskMethodBuilder 实例。

  • Start:开始执行异步方法,调用状态机的 MoveNext 方法。

  • AwaitUnsafeOnCompleted:注册回调函数,当任务完成时触发回调。

  • SetResult:设置任务的结果。

  • SetException:设置任务的异常。

AsyncTaskMethodBuilder 的内部实现

AsyncTaskMethodBuilder 内部维护了一个 Task 对象,用于表示异步操作的结果。当异步方法完成时,SetResult 方法会设置任务的结果,SetException 方法会设置任务的异常。

public struct AsyncTaskMethodBuilder<TResult>
{private Task<TResult> task;public static AsyncTaskMethodBuilder<TResult> Create(){return new AsyncTaskMethodBuilder<TResult>(new Task<TResult>());}private AsyncTaskMethodBuilder(Task<TResult> task){this.task = task;}public void Start<TStateMachine>(ref TStateMachine stateMachine)where TStateMachine : IAsyncStateMachine{stateMachine.MoveNext();}public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)where TAwaiter : INotifyCompletionwhere TStateMachine : IAsyncStateMachine{awaiter.OnCompleted(stateMachine.MoveNext);}public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)where TAwaiter : ICriticalNotifyCompletionwhere TStateMachine : IAsyncStateMachine{awaiter.UnsafeOnCompleted(stateMachine.MoveNext);}public void SetResult(TResult result){task.SetResult(result);}public void SetException(Exception exception){task.SetException(exception);}public Task<TResult> Task => task;
}

6. 异步方法的生命周期

异步方法的生命周期可以分为以下几个阶段:

  1. 初始化:创建状态机实例,初始化状态和任务构建器。

  2. 开始执行:调用 Start 方法开始执行异步方法。

  3. 执行方法体:在 MoveNext 方法中,根据当前状态执行相应的代码。

  4. 遇到 await:检查任务是否完成,如果未完成则注册回调并暂停方法执行。

  5. 任务完成:回调被触发,重新调用 MoveNext 方法,恢复异步方法的执行。

  6. 方法完成:所有异步操作完成,设置任务的结果或异常。

7. 异步方法的优势

使用 async 和 await 编写的异步方法有以下优势:

  • 提高响应性:异步方法不会阻塞主线程,应用程序可以继续响应用户的输入和其他事件。

  • 提高性能:异步方法可以并发执行多个任务,充分利用系统资源。

  • 简化代码:异步方法的代码结构类似于同步方法,易于理解和维护。

8. 异步方法的注意事项

尽管 async 和 await 提供了许多优势,但在使用时也需要注意以下几点:

  • 避免 async voidasync void 方法主要用于事件处理程序,其他情况下应避免使用,因为它无法被等待,并且异常处理较为困难。

  • 异常处理:异步方法中的异常会被包装在 AggregateException 中,需要特殊处理。

  • 资源管理:异步方法中使用 using 语句时,需要注意 Dispose 方法的调用时机。

9. 完整的流程图

为了更好地理解这个过程,可以用流程图来展示:

总结

通过上述详细的解释和示例代码,我们可以总结出以下几点:

  1. 异步方法的基本概念async 和 await 关键字用于编写异步代码。

  2. 状态机的生成:编译器为每个异步方法生成一个状态机,包含所有局部变量和状态信息。

  3. MoveNext 方法的执行MoveNext 方法是状态机的核心,负责管理和执行异步操作。

  4. 回调函数的注册和触发:当遇到 await 关键字时,编译器会生成代码来检查任务是否已经完成。如果任务未完成,注册回调并暂停方法执行。当任务完成时,回调函数会被触发,重新调用状态机的 MoveNext 方法,从而恢复异步方法的执行。

  5. AwaitUnsafeOnCompleted 方法的作用:在任务完成时注册一个回调函数,回调函数会在任务完成后被触发,从而恢复异步方法的执行。

文章转载自:极客Bob

原文链接:https://www.cnblogs.com/Bob-luo/p/18518463

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

关键字:英文作文_东莞市企慕网络科技有限公司_海南百度推广总代理商_各种网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: