我试图了解Async和Await的工作方式。如何控制程序中的行程。这是我试图理解的代码。
public async Task MyMethod()
{
Task<int> 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<int> 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<int> longRunningTask = await LongRunningOperation();
要么
int result = await longRunningTask;
请有人可以向我解释上面不清楚的代码。
1)如果longRunningOperation尚未完成并仍在运行,则MyMethod()将返回其调用方法,因此主线程不会被阻塞。当longRunningOperation完成时,来自ThreadPool的线程(可以是任何线程)将以其先前状态返回MyMethod()并继续执行(在这种情况下,将结果打印到控制台)。
第二种情况是longRunningOperation已经完成其执行并且结果可用。当到达await longRunningOperation时,编译器知道它具有结果,并将继续在同一线程上执行代码。 (在这种情况下,将结果打印到控制台)。
我一点都不明白第1点像语句“
if the longRunningOperation hasn't finished and is still running, MyMethod() will return to its calling method
”如果可能,请更详细地说明第一点。谢谢
最佳答案
我的博客上有一个 async
intro,可能会对您有所帮助。
这段代码:
int result = await LongRunningOperation();
基本上与此代码相同:
Task<int> resultTask = LongRunningOperation();
int result = await resultTask;
因此,是的,该方法直接调用
LongRunningOperation
。当
await
运算符传递给已经完成的任务时,它将提取结果并继续执行该方法(同步)。当
await
运算符传递给不完整的任务时(例如,LongRunningOperation
返回的任务将不完整),然后默认情况下await
将捕获当前上下文并从方法中返回不完整的任务。稍后,当
await
任务完成时,该方法的其余部分计划在该上下文中运行。除非它是
SynchronizationContext.Current
,否则此“上下文”是null
,在这种情况下,它是TaskScheduler.Current
。如果您在控制台应用程序中运行此命令,则该上下文通常是线程池上下文,因此async
方法将继续在线程池线程上执行。但是,如果您在UI线程上执行相同的方法,则上下文是UI上下文,并且async
方法将继续在UI线程上执行。