async 和 await 之本质

反编译,大概过程是:

- 创建一个结构体保存这个任务需要的内容,包括委托,状态标记,TaskAwaiter

- 通过Task.Run执行异步方法,之后持续对Task状态进行判断。

- 当执行完毕后通过task.GetResult()获取返回值。

剩余疑问:

- MoveNext应该是持续调用的,但不知道谁在调用。

- 异步执行完毕后执行主线程剩余代码,是如何返回主线程的(还是一直就是在主线程上执行?为何不造成阻塞)

internal class Program

{

// Methods

[AsyncStateMachine(typeof(<Async2>d__2)), DebuggerStepThrough]

private static void Async2()

{

<Async2>d__2 d__;

d__.<>t__builder = AsyncVoidMethodBuilder.Create();

d__.<>1__state = -1;

d__.<>t__builder.Start<<Async2>d__2>(ref d__);

}

private static void Main(string[] args)

{

Async2();

Console.WriteLine("aaa");

Console.ReadLine();

}

// Nested Types

[CompilerGenerated]

private struct <Async2>d__2 : IAsyncStateMachine

{

// Fields

public int <>1__state;

public AsyncVoidMethodBuilder <>t__builder;

private object <>t__stack;

private TaskAwaiter <>u__$awaiter3;

// Methods

private void MoveNext()

{

try

{

TaskAwaiter awaiter;

bool flag = true;

switch (this.<>1__state)

{

case -3:

goto Label_00C5;

case 0:

break;

default:

if (Program.CS$<>9__CachedAnonymousMethodDelegate1 == null)

{

Program.CS$<>9__CachedAnonymousMethodDelegate1 = new Action(Program.<Async2>b__0);

}

awaiter = Task.Run(Program.CS$<>9__CachedAnonymousMethodDelegate1).GetAwaiter();

if (awaiter.IsCompleted)

{

goto Label_0090;

}

this.<>1__state = 0;

this.<>u__$awaiter3 = awaiter;

this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, Program.<Async2>d__2>(ref awaiter, ref this);

flag = false;

return;

}

awaiter = this.<>u__$awaiter3;

this.<>u__$awaiter3 = new TaskAwaiter();

this.<>1__state = -1;

Label_0090:

awaiter.GetResult();

awaiter = new TaskAwaiter();

Console.WriteLine("ccc");

}

catch (Exception exception)

{

this.<>1__state = -2;

this.<>t__builder.SetException(exception);

return;

}

Label_00C5:

this.<>1__state = -2;

this.<>t__builder.SetResult();

}

[DebuggerHidden]

private void SetStateMachine(IAsyncStateMachine param0)

{

this.<>t__builder.SetStateMachine(param0);

}

}

public delegate int MyDelegate(int x);

}

外部链接

时间: 2024-08-02 19:05:30

async 和 await 之本质的相关文章

Promise,Async,await简介

Promise 对象 转载:http://wiki.jikexueyuan.com/project/es6/promise.html 基本用法 ES6 原生提供了 Promise 对象.所谓 Promise 对象,就是代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理. 有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数.此外,Promise 对象提供的接口,使得控制异步操作更加容易.Promise

[C#]剖析异步编程语法糖: async和await

一.难以被接受的async 自从C#5.0,语法糖大家庭又加入了两位新成员: async和await. 然而从我知道这两个家伙之后的很长一段时间,我甚至都没搞明白应该怎么使用它们,这种全新的异步编程模式对于习惯了传统模式的人来说实在是有些难以接受,不难想象有多少人仍然在使用手工回调委托的方式来进行异步编程.C#中的语法糖非常多,从自动属性到lock.using,感觉都很好理解很容易就接受了,为什么偏偏async和await就这么让人又爱又恨呢? 我想,不是因为它不好用(相反,理解了它们之后是非常

自己实现async和await

无意当中看了一些博文,说有人想自己尝试实现基于异步操作的方法: 1)直接使用Task(不说咯,这个是微软给我们的标准实现方法). 2)必须继承INotifyCompletion接口,同时自己实现IsCompleted(可选)和Result(可选),GetResult(必须)和OnCompleted(必须)方法: 下面是一个具体的例子(自实现异步函数): public interface IAwait<out T> : INotifyCompletion { bool IsCompleted {

Async 与 Await 关键字研究

1        Aynsc 和 Await 关键字的研究 在 .NET 4.0 以后,基于 Task 的异步编程模式大行其道,因其大大简化了异步编程所带来的大量代码工作而深受编程人员的欢迎,如果你曾经使用过 APM(基于 IAsyncResult) 和 EAP( 基于 event/delegate),那么你一定感受颇深. 而随之而来.NET 4.5 的两个关键字 async 和 await 又使得异步编程如编写顺序的代码一样容易,特别是 async 对 委托(Lamda/LINQ 表达式,匿名

第十五节:深入理解async和await的作用及各种适用场景和用法

一. 同步VS异步 1.   同步 VS 异步 VS 多线程 同步方法:需要等待返回结果,才可以继续往下执行业务 异步方法:无须等待返回结果,可以继续往下执行业务 开启新线程:在主线程之外开启一个新的线程去执行业务 同步方法和异步方法的本质区别: 是否需要等待返回结果才能继续执行业务 2. 常见的异步方法(都以Async结尾) ① HttpClient类:PostAsync.PutAsync.GetAsync.DeleteAsync ② EF中DbContext类:SaveChangesAsyn

async(await)函数和 Generator 函数 区别

async 函数是 Generator 函数的语法糖. async 函数对 Generator 函数的改进体现在: 1. async 内置执行器. Generator 函数的执行必须靠执行器,需要调用 next() 方法,或者用co 模块:而 async 函数自带执行器.也就是说,async 函数的执行与普通函数一模一样,只要一行. 2. 更好的语义. async 和 await 比起星号和 yield,语义更清楚. 3.更广的适用性. co 模块约定,yield 命令后面只能是 Thunk 函

说说C#的async和await 解决卡顿问题 转

C# 5.0中引入了async 和 await.这两个关键字可以让你更方便的写出异步代码. 看个例子: 可以看到,async和await关键字只是把上面的代码变得更简单易懂而已. public class MyClass { public MyClass() { DisplayValue(); //这里不会阻塞 System.Diagnostics.Debug.WriteLine("MyClass() End."); } public Task<double> GetVal

【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的. 二.同步代码存在的问题 对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个

async 与 await 线程调用顺序

用async做一个多线程下载并在datagridview中即时更新,运行时在达到4个线程同时下载时界面卡顿,多次尝试后是不知道async与await线程调用顺序造成. 进入async方法后在调用await之前代码都在主线程(调用线程)中运行,调用await时及之后的async方法代码将另起线程运行该部分代码,而主线程在遇到await后回到主线程继续执行async后的代码. 将async方法通过声明委托后用begininvoke调用后解决.