• Task.WaitAll和Task.WaitAny


    Task.WaitAll和Task.WaitAny

    一、简介

    Task.WaitAll:等待所有提供的 Task 对象完成执行过程。Task.WaitAny:等待提供的任一 Task 对象完成执行过程。

    二、代码案例

    Task.WaitAll

    代码:

       class Program
        {
            public class DownLoadTest
            {
                Stopwatch watch = new Stopwatch();
                public  DownLoadTest()
                {
                    watch.Start();
                }
                    
                public async Task DoRunTaskAsync(string url, CancellationToken ct)
                {
                    if (ct.IsCancellationRequested)
                    {
                        Console.WriteLine(string.Format("取消{0}的運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                        return;
                    }
                    Console.WriteLine(string.Format("下載{0}開始運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                    WebClient wc = new WebClient();
                    await Task.Run(() =>
                    {
                        var task = wc.DownloadStringTaskAsync(url);
                        while (!task.IsCompleted)
                        {
                            if (ct.IsCancellationRequested)
                            {
                                Console.WriteLine(string.Format("取消{0}的運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                                return;
                            }
                        }
                        if (task.IsCompleted)
                            Console.WriteLine(string.Format("下載{0}運行結束 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                    });
                }
            }
    
            static void Main(string[] args)
            {
    
                DownLoadTest dwtest = new DownLoadTest();
                CancellationTokenSource cts = new CancellationTokenSource();
                CancellationToken token = cts.Token;
                var task1 = dwtest.DoRunTaskAsync("https://www.baidu.com/", token);
                var task2 = dwtest.DoRunTaskAsync("https://www.taobao.com/", token);
                var task3 = dwtest.DoRunTaskAsync("https://www.cnblogs.com/", token);
                Task[] tasks = new Task[] { task1, task2, task3 };
                Console.WriteLine("task.Result等待結果打印");
                Task.WaitAll(tasks, 10000);
                cts.Cancel();//超过10s时间取消运行
                Console.WriteLine(task1.Status);
                Console.WriteLine(task2.Status);
                Console.WriteLine(task3.Status);
                Console.WriteLine(string.Format("主線程運行結束"));
                Console.ReadKey();
            }
        }

    运行结果:

    通过运行结果可以看出,可以看到Task.WaitAll(tasks)在等待超时的时间内,同步等待了所有的任务完成。

    Task.WaitAny

    代码:

      class Program
        {
            public class DownLoadTest
            {
                Stopwatch watch = new Stopwatch();
                public  DownLoadTest()
                {
                    watch.Start();
                }
                    
                public async Task DoRunTaskAsync(string url, CancellationToken ct)
                {
                    if (ct.IsCancellationRequested)
                    {
                        Console.WriteLine(string.Format("取消{0}的運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                        return;
                    }
                    Console.WriteLine(string.Format("下載{0}開始運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                    WebClient wc = new WebClient();
                    await Task.Run(() =>
                    {
                        var task = wc.DownloadStringTaskAsync(url);
                        while (!task.IsCompleted)
                        {
                            if (ct.IsCancellationRequested)
                            {
                                Console.WriteLine(string.Format("取消{0}的運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                                return;
                            }
                        }
                        if (task.IsCompleted)
                            Console.WriteLine(string.Format("下載{0}運行結束 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                    });
                }
            }
    
            static void Main(string[] args)
            {
    
                DownLoadTest dwtest = new DownLoadTest();
                CancellationTokenSource cts = new CancellationTokenSource();
                CancellationToken token = cts.Token;
                var task1 = dwtest.DoRunTaskAsync("https://www.baidu.com/", token);
                var task2 = dwtest.DoRunTaskAsync("https://www.taobao.com/", token);
                var task3 = dwtest.DoRunTaskAsync("https://www.cnblogs.com/", token);
                Task[] tasks = new Task[] { task1, task2, task3 };
                Console.WriteLine("task.Result等待結果打印");
                Task.WaitAny(tasks, 4000);
                cts.Cancel();//超过4s时间取消运行
                Console.WriteLine(task1.Status);
                Console.WriteLine(task2.Status);
                Console.WriteLine(task3.Status);
                Console.WriteLine(string.Format("主線程運行結束"));
                Console.ReadKey();
            }
        }

    运行结果:

    通过运行结果截图可以看出,可以看到,Task.WhenAny(tasks)至少等待了一个任务的完成。这里https://www.baidu.com/先下载完,就直接终止等待 。

     

    三、总结

    Task.WaitAll阻止当前线程,直到所有其他任务完成执行为止。Task.WaitAny阻止当前线程,至少等待一个任务完成执行为止。如果等待时长设置较长,上述案例结果会一样。


    技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
    我创建了一个.NET开发交流群,用于分享学习心得和讨论相关技术难题。欢迎有兴趣的小伙伴扫码入群,相互学习!

  • 相关阅读:
    分治算法
    【原创】KFold函数 __init__() got an unexpected keyword argument 'n_folds' or 'n_splits'
    【原创】【Mac】创建可以双击执行Shell脚本文件(类似windows批处理脚本)
    【原创】【Python】随机生成中文姓名
    【原创】【word】两步搞定姓名2个字加空格对齐
    数据结构与算法——冒泡排序及其各种优化变形详解
    CobaltStrike去除流量特征
    Fastjson1.2.24RCE漏洞复现
    Redis奇怪的姿势
    Apache Druid 远程代码执行 CVE-2021-25646 漏洞复现
  • 原文地址:https://www.cnblogs.com/wml-it/p/14861839.html
Copyright © 2020-2023  润新知