简体   繁体   English

异步并等待:为什么其签名定义了Task的返回类型的异步方法显式地返回Task?

[英]Async and await: Why doesn't an async method whose signature defines a return type of Task explicitly return a Task?

I used How to: Extend the async Walkthrough by Using Task.WhenAll (C#) to develop a program to independently submit multiple database queries asynchronously. 我使用了如何:通过使用Task.WhenAll(C#)扩展异步演练来开发一个程序,以独立地异步提交多个数据库查询。 The program works ok, but there is a nuance I don't understand and for which I can't find an explanation: 该程序可以正常运行,但是有一个我不理解的细微差别,对此我无法找到解释:

In the example, the signature for the method SumPageSizesAsync is: 在示例中,方法SumPageSizesAsync的签名为:

private async Task SumPageSizesAsync()

The body of the method SumPageSizesAsync does not explicitly return the whenAllTask object (ie, the WhenAll roll-up Task ). 方法SumPageSizesAsync的主体未显式返回whenAllTask对象(即, WhenAll汇总Task )。 Why doesn't the method SumPageSizesAsync explicitly return the whenAllTask task? 为什么SumPageSizesAsync方法SumPageSizesAsync显式返回whenAllTask任务? How does the line of code in StartButton_Click that calls SumPageSizesAsync "know" which task is being returned? StartButton_Click中调用SumPageSizesAsync的代码行如何“知道”正在返回哪个任务?

private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    .
    Task sumTask = SumPageSizesAsync();
    .
}


private async Task SumPageSizesAsync()
{
    HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };

    List<string> urlList = SetUpURLList();

    IEnumerable<Task<int>> downloadTasksQuery = from url in urlList select ProcessURLAsync(url);
    Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

    Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);

    int[] lengths = await whenAllTask;

    int total = lengths.Sum();

    // Display the total count for all of the web addresses.  
    resultsTextBox.Text += string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);

    // where's the return statement?
}

Why doesn't the method SumPageSizesAsync explicitly return the whenAllTask task? 为什么SumPageSizesAsync方法没有显式返回whenAllTask​​任务?

That is not the Task that this method returns. 这不是此方法返回的Task。 The Task that is returned is one that is created by the compiler. 返回的任务是由编译器创建的任务。
As soon as the await is encountered, the following happens: 一旦遇到await ,就会发生以下情况:
- If whenAllTask is already finished, then just continue executing the rest of the method. -如果whenAllTask已经完成,则只需继续执行该方法的其余部分即可。
- Otherwise, create a Task that does the following things: -否则,请创建执行以下Task
1: Wait for whenAllTask to finish. 1:等待whenAllTask完成。
2: and then execute the rest of the method. 2:然后执行其余方法。
This Task is then immediately returned. 然后立即返回此Task
I always think of the return statement as being embedded in the await . 我一直认为return语句嵌入在await "return a Task that waits for this other Task to finish and then executes the rest of this method." “返回一个等待其他任务完成的任务,然后执行此方法的其余部分。”

I completely agree on answer posted by @Dennis_E and more information can also be found in C# 6 in a Nutshell (page number 600). 我完全同意@Dennis_E发布的答案 ,更多信息也可以在C#6的“ Nutshell” (页码600)中找到。

According to author, while executing the async function, with task return type. 据作者介绍,在执行异步功能时,具有任务返回类型。 If there is no explicit return of task from the method body, complier creates a task . 如果没有从方法体中明确返回任务,则编译器将创建一个task

This task is then used for following purpose, 然后,此任务用于以下目的,

  1. Singling completion of the method. 该方法的完成。
  2. Asynchronous call chaining. 异步呼叫链接。

It is an async void function, meaning it returns Task. 这是一个异步void函数,表示它返回Task。 Since it is already awaited inside, there is nothing no return here. 由于已经在里面等待了,所以这里没有任何回报。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM