.net中Task.WhenAll和WhenAny异步的等待Task完成

前面讲了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/先下载完,就直接终止等待


posted @ 2018-04-05 17:06  huey-chan  阅读(365)  评论(0编辑  收藏  举报