是否立即运行其命令来调用异步方法

时间:2019-05-15 11:49:11

标签: c# async-await task task-parallel-library

我得到了以下代码:

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>(() => ...);

的操作

2 个答案:

答案 0 :(得分:3)

我建议阅读我的async intro

总而言之,所有async方法都开始同步执行。因此,当AsynchronousProcessing调用GetInfoAsync时,GetInfoAsync就开始同步运行,就像其他方法一样。如果有async,则await方法可能会变得异步。在这种情况下,GetInfoAsync调用Task.Delay(同样,与常规方法调用一样,是同步进行的),然后将其Task传递给await。此时,await将检查任务;如果已经完成,则它将继续同步运行;否则,它将异步执行,并从GetInfoAsync返回不完整的任务。

async方法返回的任务正在进行中。我通常不使用“正在运行”一词,因为它们实际上并不是在CPU上运行代码,并且因为任务状态实际上不是RunningThis "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(..)完成时,可能会使用另一个线程。 awaitresume on its captured context并在该上下文中执行return "hi";。如果捕获的上下文是线程池上下文,则将在线程池线程上执行一行代码。 async状态机将return转换为可完成先前从该async方法返回的任务的代码。

答案 1 :(得分:0)

GetInfoAsync被调用并像往常一样同步运行,直到到达await Task.Delay(TimeSpan.FromSeconds(seconds))行为止。然后,它将未完成的任务返回给调用的AsynchronousProcessing()方法。

是的,当您调用该方法时,任务确实正在启动,即您不必等待GetInfoAsync来调用Task.Delay方法。