如果我不关心任务完成的顺序,只需要完成它们,我还应该使用await Task.WhenAll而不是多个await吗?例如,DoWork2低于优选的方法DoWork1(以及为什么?):
using System;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
static async Task<string> DoTaskAsync(string name, int timeout)
{
var start = DateTime.Now;
Console.WriteLine("Enter {0}, {1}", name, timeout);
await Task.Delay(timeout);
Console.WriteLine("Exit {0}, {1}", name, (DateTime.Now - start).TotalMilliseconds);
return name;
}
static async Task DoWork1()
{
var t1 = DoTaskAsync("t1.1", 3000);
var t2 = DoTaskAsync("t1.2", 2000);
var t3 = DoTaskAsync("t1.3", 1000);
await t1; await t2; await t3;
Console.WriteLine("DoWork1 results: {0}", String.Join(", ", …Run Code Online (Sandbox Code Playgroud) .net c# parallel-processing task-parallel-library async-await
我正在阅读Stephen Cleary撰写的"C#Cookbook中的并发",我注意到以下技巧:
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
return null;
return await downloadTask;
Run Code Online (Sandbox Code Playgroud)
downloadTask是对httpclient.GetStringAsync的调用,timeoutTask正在执行Task.Delay.
如果它没有超时,则downloadTask已经完成.为什么有必要做第二次等待而不是返回downloadTask.Result,因为任务已经完成了?
我有一个异步方法,GetExpensiveThing()它执行一些昂贵的I/O工作.这就是我使用它的方式:
// Serial execution
public async Task<List<Thing>> GetThings()
{
var first = await GetExpensiveThing();
var second = await GetExpensiveThing();
return new List<Thing>() { first, second };
}
Run Code Online (Sandbox Code Playgroud)
但由于这是一种昂贵的方法,我想并行执行这些调用.我本以为移动等待会解决这个问题:
// Serial execution
public async Task<List<Thing>> GetThings()
{
var first = GetExpensiveThing();
var second = GetExpensiveThing();
return new List<Thing>() { await first, await second };
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,所以我将它们包装在一些任务中,这有效:
// Parallel execution
public async Task<List<Thing>> GetThings()
{
var first = Task.Run(() =>
{
return GetExpensiveThing();
});
var second = Task.Run(() =>
{ …Run Code Online (Sandbox Code Playgroud)