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阻止当前线程,至少等待一个任务完成执行为止。如果等待时长设置较长,上述案例结果会一样。
本文来自博客园,作者:码农阿亮,转载请注明原文链接:https://www.cnblogs.com/wml-it/p/14861839.html
技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
开源库地址,欢迎点亮:
GitHub:https://github.com/ITMingliang
Gitee: https://gitee.com/mingliang_it
GitLab: https://gitlab.com/ITMingliang
建群声明: 本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,为大家答疑解惑。热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得!进群方式:扫码关注公众号,后台回复【进群】。