想象一下,我有一个异步函数,它从一个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的状态?
答案 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);
}