使用async / await重写多线程等待

时间:2012-10-03 18:37:46

标签: c# multithreading async-await c#-5.0

我们有一个webservice函数,它在后台运行一系列任务。当所有任务完成后,它将返回。我重新考虑了C#5的功能。我设法让以下代码段工作:

var result = new List<int>();
var tasks = new List<Task<int>>();

foreach (var row in rowlist)
    tasks.Add(Task.Factory.StartNew(() => DoWork(row)));
foreach (var task in tasks)
    result.Add(task.Result);

task.Result等待完成单个任务。我已经通过向DoWork方法添加了3秒的延迟并验证它在不到5秒的时间内完成测试,以获得10个任务的列表。

现在我尝试使用新的async / await语法重写该函数。但我似乎无法让它发挥作用。如果它编译,它会同步运行,通过添加等待验证。

有关如何使用async / await重写上述代码段的任何想法?

2 个答案:

答案 0 :(得分:9)

我会把它写成:

var tasks = rowlist.Select(row => Task.Run(() => DoWork(row)));

var results = (await Task.WhenAll(tasks)).ToList();

基本上,您仍然可以按照以前的方式创建任务(不使用await),因为您希望它们全部立即启动。然后,您可以等待所有这些异步完成(通过await Task.WhenAll),然后立即取出结果(因为您知道它们已完成)。

答案 1 :(得分:2)

根据Reed Copsey,Servy和Stephen Cleary的回答和评论,我已经推进了这个解决方案:

var results = rowlist
    .Select(row => Task.Run(() => DoWork(row)))
    .ToList()
    .Select(t => t.Result);

第二个Select将等待任务完成。我之间添加了一个ToList()来防止流式传输,但似乎没有它。