Async和Await的工作原理

我试图了解Async和Await是如何工作的。 如何控制程序中的旅行。 这是我试图理解的代码。

public async Task MyMethod() { Task longRunningTask = LongRunningOperation(); //indeed you can do independent to the int result work here MySynchronousMethod(); //and now we call await on the task int result = await longRunningTask; //use the result Console.WriteLine(result); } public async Task LongRunningOperation() // assume we return an int from this long running operation { await Task.Delay(5000); //5 seconds delay return 1; } private void Button_Click_3(object sender, RoutedEventArgs e) { MyMethod(); } 

当按钮单击发生时,将MyMethod()并且将调用MyMethod LongRunningOperation() ,并且需要5秒才能完成。 所以我的问题是

  • 这条线的意义是什么

    任务longRunningTask = LongRunningOperation();

  • 这会做什么int result = await longRunningTask;

上面的行可以提交,我们可以构建一行代码

 Task longRunningTask = await LongRunningOperation(); 

要么

 int result = await longRunningTask; 

请有人向我解释上面的代码,这对我来说并不清楚。

1)如果longRunningOperation尚未完成且仍在运行,MyMethod()将返回其调用方法,因此主线程不会被阻塞。 当完成longRunningOperation时,来自ThreadPool的线程(可以是任何线程)将返回其先前状态的MyMethod()并继续执行(在这种情况下将结果打印到控制台)。

第二种情况是longRunningOperation已经完成执行并且结果可用。 当到达等待longRunningOperation时,编译器知道它具有结果并将继续在同一个线程上执行代码。 (在这种情况下打印结果到控制台)。

第1点对我来说一点也不清楚“ if the longRunningOperation hasn't finished and is still running, MyMethod() will return to its calling method

如果可能的话,更详细地解释一点。 谢谢

我在我的博客上有一个async介绍 ,你可能会觉得有帮助。

这段代码:

 int result = await LongRunningOperation(); 

与此代码基本相同:

 Task resultTask = LongRunningOperation(); int result = await resultTask; 

所以,是的, LongRunningOperation是由该方法直接调用的。

await运算符传递已完成的任务时,它将提取结果并继续执行该方法(同步)。

await运算符传递一个不完整的任务(例如, LongRunningOperation返回的任务将不会完成)时,默认情况下await将捕获当前上下文并从该方法返回一个不完整的任务。

稍后,当await任务完成时,该方法的其余部分将安排在该上下文中运行。

这个“上下文”是SynchronizationContext.Current除非它是null ,在这种情况下它是TaskScheduler.Current 。 如果您在控制台应用程序中运行此操作,则上下文通常是线程池上下文,因此async方法将在线程池线程上继续执行。 但是,如果在UI线程上执行相同的方法,则上下文是UI上下文, async方法将在UI线程上继续执行。

我以下列方式接受过这方面的教育,我发现这是一个非常简洁明了的解释:

 //this is pseudocode async Method() { code; code; await something; moreCode; } 

当调用Method ,它会执行其内容( code;行)直到await something; 。 那时, something; 被解雇了,方法就像return; 在那里。

something; 做它需要然后返回。

something; 返回,执行返回到Method并从await继续执行,执行moreCode;

以更加示意性的方式,这是发生的事情:

  1. 调用方法
  2. code; 被执行
  3. something; 执行后,流程返回到调用Method的位置
  4. 执行继续在Method调用之后发生的事情
  5. something; 返回,流返回Method里面
  6. moreCode; 执行并且Method本身结束(是的,可能还有其他东西await它,依此类推等等)

在幕后,C#编译器实际上将您的代码转换为状态机。 它会生成更多代码,以便每次等待任务或异步操作完成后,它都会在幕后继续执行。 就您的问题而言,每次异步操作完成时,当您最初启动对异步方法的调用时,将在调用线程上回调异步方法。 例如,它将在您开始的线程上执行您的代码。 因此,异步操作将在Task线程上运行,然后结果将返回到最初调用该方法的线程并继续执行。

await将从Task或async操作获取值,并在返回执行时从任务中“取消装箱”。在这种情况下,它会自动将其放入int值,因此无需存储Task。

您的代码有问题,它等待LongRunningTask()你很可能只想在没有异步的情况下返回长任务方法,然后让你的MyMethod执行await。

int value = await LongWaitingTask()

http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine

您需要异步方法才能返回Task或void。

可以更改它,以便当您从执行异步任务返回时,它将执行使用http://msdn.microsoft.com/en-us/library/system执行异步任务的线程上的剩余代码。 threading.tasks.task.configureawait(v = vs.110)的.aspx