异步方法在等待循环中的某些东西时如何工作?

时间:2018-04-04 13:30:04

标签: c# async-await

想象一下,我有一个异步函数,它从一个url获取数据并将其输出到一个文件,以及一个async函数,它调用url列表的第一个函数,如下所示:

static async Task UrlToFileAsync(Uri url, string filePath)
{
    //...
}

public static async Task GetDataAsync(List<Uri> urlList, string filePath)
{
    foreach (Uri url in urlList)
    {
        await UrlToFileAsync(url, filePath);
    }
}

我的问题是,当循环中调用的每个url的Task完成后,GetDataAsync的Task是否只被视为已完成?程序是否在某处创建了一个数组或任务列表来监视每次调用UrlToFileAsync的状态?

1 个答案:

答案 0 :(得分:4)

  

当循环中调用的每个url的Task完成后,GetDataAsync中的Task是否仅被视为已完成?

是的,这是正确的。

  

程序是否在某处创建了一个数组或任务列表来监控每次UrlToFileAsync调用的状态?

您正在等待UrlToFileAsync(),因此当方法完成时,执行将返回GetDataAsync()。 async / await基本上让你的应用程序在执行I / O工作时释放它使用回线程池的线程,并且一旦I / O工作完成,它将恢复CPU绑定执行并最终返回到上下文调用方法。对here有更详细的解释。您还可以在Stephen Cleary's blog找到更多信息。

目前,您按顺序运行每个网址,因此您没有充分利用asyinc / await的全部优势。如果要并行化任务,则应该执行以下操作:

public static async Task GetDataAsync(List<Uri> urlList, string filePath)
{
    // create an array of tasks
    var tasks = urlList.Select(u => UrlToFileAsync(u, filePath)).ToArray();
    // wait for them all to complete
    await Task.WhenAll(tasks);
}