我得到了以下代码:
static async Task AsynchronousProcessing()
{
Task<string> t1 = GetInfoAsync("Task 1", 3);
Task<string> t2 = GetInfoAsync("Task 2", 5);
string[] results = await Task.WhenAll(t1, t2);
foreach (string result in results)
{
WriteLine(result);
}
}
static async Task<string> GetInfoAsync(string name, int seconds)
{
await Task.Delay(TimeSpan.FromSeconds(seconds));
return "hi";
}
到达行Task<string> t1 = GetInfoAsync("Task 1", 3);
时,它是否已经与await Task.Delay(TimeSpan.FromSeconds(seconds));
异步启动并继续到方法的其余部分,还是会立即返回任务而不实际启动它?
如果在调用方法时无法启动,则仅在调用Task.WhenAll(t1,t2)
时任务才能启动吗?由于如果不能立即开始,我希望看到GetInfoAsync
做类似return new Task<string>(() => ...);
答案 0 :(得分:3)
我建议阅读我的async
intro。
总而言之,所有async
方法都开始同步执行。因此,当AsynchronousProcessing
调用GetInfoAsync
时,GetInfoAsync
就开始同步运行,就像其他方法一样。如果有async
,则await
方法可能会变得异步。在这种情况下,GetInfoAsync
调用Task.Delay
(同样,与常规方法调用一样,是同步进行的),然后将其Task
传递给await
。此时,await
将检查任务;如果已经完成,则它将继续同步运行;否则,它将异步执行,并从GetInfoAsync
返回不完整的任务。
从async
方法返回的任务正在进行中。我通常不使用“正在运行”一词,因为它们实际上并不是在CPU上运行代码,并且因为任务状态实际上不是Running
。 This "asynchronous in-progress" state is unfortunately named WaitingForActivation
(即使它没有等待任何东西)。
由于它不能立即开始,因此我希望看到GetInfoAsync可以执行类似return new Task(()=> ...);
async
关键字处理任务的创建。如上所述,任务是“热”或“进行中”。这与“正在运行”或“已启动”不同,两者都暗示着运行CPU代码的任务。 There are two types of tasks: what I call Delegate Tasks and Promise Tasks。从async
方法返回的是Promise Tasks。
如果没有任何新线程正在等待,那么它们将如何并行运行?
它们同时运行 (不是在 parallel 中运行,因为在延迟上没有其他线程被阻塞)。
但是,await Task.Delay(..)
完成时,可能会使用另一个线程。 await
将resume on its captured context并在该上下文中执行return "hi";
。如果捕获的上下文是线程池上下文,则将在线程池线程上执行一行代码。 async
状态机将return
转换为可完成先前从该async
方法返回的任务的代码。
答案 1 :(得分:0)
GetInfoAsync
被调用并像往常一样同步运行,直到到达await Task.Delay(TimeSpan.FromSeconds(seconds))
行为止。然后,它将未完成的任务返回给调用的AsynchronousProcessing()
方法。
是的,当您调用该方法时,任务确实正在启动,即您不必等待GetInfoAsync
来调用Task.Delay
方法。