前面讲了Task.WaitAll和WaitAny同步的等待Task完成,在异步方法中,我们希望用await表达式等待Task,这里使用Task.WhenAll和WhenAny方法来实现等待一个或者多个任务完成。
修改Main函数,添加一个异步方法,代码如下:
static void Main(string[] args)
{
string[] urls = { "https://stackoverflow.com/" , "https://github.com/" };
var task = DoRunsAsync(urls);
task.Wait();
Debug.WriteLine(string.Format("主线程运行结束"));
Console.ReadKey();
}
private static async Task<string> DoRunsAsync(IEnumerable<string> urls)
{
DownLoadTest dwtest = new DownLoadTest();
List<Task> tasks = new List<Task>();
foreach (var url in urls)
{
var task = dwtest.DoRunStringAsync(url);
Debug.WriteLine("task.Id =" + task.Id + " url=" + url);
tasks.Add(task);
}
await Task.WhenAll(tasks);
foreach (var task in tasks)
{
Debug.WriteLine("task.Id =" + task.Id + " task.Status=" + task.Status);
}
return "";
}
执行结果如下:
异步程序获取https://stackoverflow.com/开始运行: 1ms
task.Id =3 url=https://stackoverflow.com/
异步程序获取https://github.com/开始运行: 50ms
下载https://stackoverflow.com/开始运行 : 51ms
下载https://github.com/开始运行 : 51ms
task.Id =6 url=https://github.com/
下载https://stackoverflow.com/运行结束 :1,965ms
异步程序获取https://stackoverflow.com/运行结束:1,966ms
下载https://github.com/运行结束 :1,995ms
异步程序获取https://github.com/运行结束:1,996ms
task.Id =3 task.Status=RanToCompletion
task.Id =6 task.Status=RanToCompletion
主线程运行结束
可以看到await Task.WhenAll(tasks);异步等待了所有的任务完成。
我们使用Task.WhenAny来看看效果:
static void Main(string[] args)
{
string[] urls = { "https://stackoverflow.com/" , "https://github.com/" };
var task = DoRunsAsync(urls);
task.Wait();
Debug.WriteLine(string.Format("主线程运行结束"));
Console.ReadKey();
}
private static async Task<string> DoRunsAsync(IEnumerable<string> urls)
{
DownLoadTest dwtest = new DownLoadTest();
List<Task> tasks = new List<Task>();
foreach (var url in urls)
{
var task = dwtest.DoRunStringAsync(url);
Debug.WriteLine("task.Id =" + task.Id + " url=" + url);
tasks.Add(task);
}
await Task.WhenAny(tasks);
foreach (var task in tasks)
{
Debug.WriteLine("task.Id =" + task.Id + " task.Status=" + task.Status);
}
return "";
}
运行结果如下:
异步程序获取https://stackoverflow.com/开始运行: 1ms
task.Id =3 url=https://stackoverflow.com/
异步程序获取https://github.com/开始运行: 52ms
下载https://stackoverflow.com/开始运行 : 52ms
task.Id =6 url=https://github.com/
下载https://github.com/开始运行 : 53ms
下载https://github.com/运行结束 :1,892ms
异步程序获取https://github.com/运行结束:1,893ms
task.Id =3 task.Status=WaitingForActivation
task.Id =6 task.Status=RanToCompletion
主线程运行结束
下载https://stackoverflow.com/运行结束 :5,009ms
异步程序获取https://stackoverflow.com/运行结束:5,010ms
可以看到,Task.WhenAny(tasks)至少等待了一个任务的完成。这里https://github.com/先下载完,就直接终止等待