考虑以下代码:
public static void Run() {
DoStuffAsync();
}
public static async Task DoStuffAsync() {
PerformCalc();
await DoLongTaskAsync();
PerformAnotherCalc();
}
比方说我打Run()
。我对行为有一些疑问:
PerformCalc()
的线程相同的线程上同步调用Run()
?DoLongTaskAsync()
被异步还是同步调用?换句话说,是否PerformAnotherCalc()
会在DoLongTaskAsync()
完成之前被调用?DoStuffAsync()
方法是否可以在DoLongAsyncTask()
执行完成之前返回?答案 0 :(得分:6)
异步方法始终 start 同步运行。魔术发生在await
,但仅当await
被赋予尚未完成的Task
时。
在您的示例中,这是您致电Run()
时发生的情况:
DoStuffAsync()
PerformCalc()
DoLongTaskAsync()
DoLongTaskAsync()
是一个真正的异步操作并返回不完整的Task
,则await
会执行其工作,而DoStuffAsync()
返回一个不完整的{ {1}}至Task
。Run()
完成。Run()
完成后,DoLongTaskAsync()
恢复,并跳到DoStuffAsync()
。所有可以发生在同一线程上。
所以回答您的问题:
PerformAnotherCalc()
方法,那么它可能最终会消失并在其他线程上运行。但是它将在同一线程上同步启动。async
将被异步调用,但是DoLongTaskAsync()
不会在PerformAnotherCalc()
完成之前被调用,因为您使用了DoLongTaskAsync()
。await
就是这样工作的。它将返回不完整的await
(也就是说,仅当Task
确实是异步的并且返回不完整的DoLongTaskAsync()
时)。然后,Task
完成后,DoLongTaskAsync()
将从中断处继续执行。答案 1 :(得分:2)
- 是否会在与调用Run()的线程相同的线程上同步调用PerformCalc()?
是的
- 会以异步方式还是同步方式调用DoLongTaskAsync()?换句话说,在DoLongTaskAsync()完成之前会调用PerformAnotherCalc()吗?
它将被同步调用,但是它可能在“长任务”操作完成之前返回Task
。无论哪种方式,都将等待它返回的Task
,因此直到从PerformAnotherCalc
返回的Task
都不会被调用DoLongTaskAsync
。
- 随后,DoStuffAsync()方法可以在DoLongAsyncTask()执行完成之前返回吗?
当DoStuffAsync
到达第一个await
时,该方法将返回(如果正在等待的Task
处于挂起状态)。这就是async
方法的工作方式-它们同步运行直到await
的第一个Task
挂起,然后返回Task
,当整个过程完成时方法已执行。
如果可能是DoLongTaskAsync
返回了已经完成的Task
:在这种情况下,DoStuffAsync
不会返回,直到PerformAnotherCalc
返回。如果DoLongTaskAsync
返回的Task
仍在等待处理,则DoStuffAsync
将在该点返回,并且将返回Task
,一旦Task
返回,则完成DoLongTaskAsync
中的内容已完成,和 PerformAnotherCalc
已返回。
答案 2 :(得分:1)
否则,请考虑以下方法:
public static void Run1() {
DoStuffAsync();
Console.WriteLine("Done");
}
public static async Task Run2() {
await DoStuffAsync();
Console.WriteLine("Done");
}
public static async Task DoStuffAsync() {
PerformCalc();
await DoLongTaskAsync();
PerformAnotherCalc();
}
在Run2
中,可以保证在PerformAnotherCalc
之后显示“完成”。在Run1
中,“完成”将在PerformCalc
之后但在PerformAnotherCalc
之前显示(假设DoLongTaskAsync
实际上是异步的,这取决于其实现)。
答案 3 :(得分:0)
所有呼叫都是同步的。如果返回的awaitable不完整,则await
可以是异步的。