C#中的Task.WhenAll和Task.WhenAny方法介绍

一、简介

Task.WhenAll()、Task.WhenAny()这两个与Task.WaitALL()、Task.WaitAny()是有区别的,When是异步的,Wait是同步的。
Task.WhenAll():所有提供的任务已完成时,创建将完成的任务。
Task.WhenAny():任何提供的任务已完成时,创建将完成的任务。

二、代码案例

Task.WhenAll

代码:

    class Program
    {
        public class DownLoadTest
        {
            Stopwatch watch = new Stopwatch();
            public DownLoadTest()
            {
                watch.Start();
            }
            public string DownLoadString(string url)
            {
                Console.WriteLine(string.Format("下載{0}開始運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                WebClient wc = new WebClient();
                string str = wc.DownloadString(url);
                Console.WriteLine(string.Format("下載{0}運行結束 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                return str;
            }

            public async Task<string> DoRunStringAsync(string url)
            {
                Console.WriteLine(string.Format("異步程序獲取{0}開始運行:{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                var task = await DownLoadStringAsync(url);
                Console.WriteLine(string.Format("異步程序獲取{0運行結束:{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                return task;
            }

            public async Task<string> DownLoadStringAsync(string url)
            {
                string str = await Task.Run(() => DownLoadString(url));
                return str;
            }
        }

        static void Main(string[] args)
        {
            string[] urls = { "https://www.baidu.com/", "https://www.taobao.com/", "https://www.cnblogs.com/" };
            var task = DoRunsAsync(urls);
            //task.Wait(3000);
            Console.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);
                Console.WriteLine("task.Id =" + task.Id + "  url=" + url);
                tasks.Add(task);
            }
            await Task.WhenAll(tasks);
            foreach (var task in tasks)
            {
                Console.WriteLine("task.Id =" + task.Id + "  task.Status=" + task.Status);
            }
            return "";
        }
    }

运行结果:

可以看到await Task.WhenAll(tasks);异步等待了所有的任务完成。

Task.WhenAny

代码:

    class Program
    {
        public class DownLoadTest
        {
            Stopwatch watch = new Stopwatch();
            public DownLoadTest()
            {
                watch.Start();
            }
            public string DownLoadString(string url)
            {
                Console.WriteLine(string.Format("下載{0}開始運行 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                WebClient wc = new WebClient();
                string str = wc.DownloadString(url);
                Console.WriteLine(string.Format("下載{0}運行結束 :{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                return str;
            }

            public async Task<string> DoRunStringAsync(string url)
            {
                Console.WriteLine(string.Format("異步程序獲取{0}開始運行:{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                var task = await DownLoadStringAsync(url);
                Console.WriteLine(string.Format("異步程序獲取{0運行結束:{1,4:N0}ms", url, watch.Elapsed.TotalMilliseconds));
                return task;
            }

            public async Task<string> DownLoadStringAsync(string url)
            {
                string str = await Task.Run(() => DownLoadString(url));
                return str;
            }
        }

        static void Main(string[] args)
        {
            string[] urls = { "https://www.baidu.com/", "https://www.taobao.com/", "https://www.cnblogs.com/" };
            var task = DoRunsAsync(urls);
            task.Wait(1000);
            Console.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);
                Console.WriteLine("task.Id =" + task.Id + "  url=" + url);
                tasks.Add(task);
            }
            await Task.WhenAny(tasks);
            foreach (var task in tasks)
            {
                Console.WriteLine("task.Id =" + task.Id + "  task.Status=" + task.Status);
            }
            return "";
        }
    }

运行结果:

Task.WhenAny(tasks)至少等待了一个任务的完成。这里https://www.baidu.com/先下载完,就直接终止等待 。

到此这篇关于C#中Task.WhenAll和Task.WhenAny方法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#中的Task.Delay()和Thread.Sleep()区别(代码案例)

    一.简介 1.Thread.Sleep()是同步延迟,Task.Delay()是异步延迟. 2.Thread.Sleep()会阻塞线程,Task.Delay()不会. 3.Thread.Sleep()不能取消,Task.Delay()可以. 4.Task.Delay()实质创建一个运行给定时间的任务,Thread.Sleep()使当前线程休眠给定时间. 5.反编译Task.Delay(),基本上讲它就是个包裹在任务中的定时器. 6.Task.Delay()和Thread.Sleep()最大的区别

  • C#使用Task.ContinueWith组合任务

    代码案例 简单Demo 代码: public static void Main() { //创建一个任务 Task<int> task = new Task<int>(() => { int sum = 0; Console.WriteLine("使用Task異步執行操作."); for (int i = 0; i <= 100; i++) { sum += i; } return sum; }); //启动任务,并安排到当前任务队列线程中执行任务(

  • C#中Task.ContinueWith连续任务使用实例

    通过任务,可以指定在任务完成之后,应开始运行之后另一个特定任务.例如,一个使用前一个任务的结果的新任务,如果前一个任务失败了,这个任务就应执行一些清理工作.任务处理程序都不带参数或者带一个对象参数,而任务的连续处理方法都有一个Task类型的参数,这里可以访问起始任务的相关信息: 如下面的示例代码:   class Program     {         static void DoOnFirst()         {             Console.WriteLine($"doin

  • C#连续任务Task.ContinueWith方法

    一.简介 通过任务,可以指定在任务完成之后,应开始运行之后另一个特定任务.ContinueWith是Task根据其自身状况,决定后续应该作何操作.也就是说,在运行完task后,会执行task.continuewith(XX)中的XX语句,但是是否执行.如何执行等需要看task的运行情况.例如:一个使用前一个任务的结果的新任务,如果前一个任务失败了,这个任务就应执行一些清理工作.任务处理程序都不带参数或者带一个对象参数,而任务的连续处理方法都有一个Task类型的参数. 二.案例 案例一: 代码:

  • C#异步编程Task的创建方式

    一.简介 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如:Task支持线程的取消.完成.失败通知等交互性操作,但是ThreadPool不支持:Task支持线程执行的先后次序,但是ThreadPool不支持::以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task.Task在线程池的基础上进行了优化,并提供了更多的API.在FCL4.0中,如果我们要编写多线程程序,Task显然已经

  • C#多线程编程Task用法详解

    目录 一.基本概念 Task优势 二.Task用法 创建任务 1.使用Task创建无返回值 2.使用Task.Run方法创建任务 3.使用Factory方式创建任务 4.创建带返回值的Task 三.常见方法 1.WaitAll() 2.WaitAny() 3.ContinueWhenAll() 4.ContinueWhenAny 5.ContinueWith 一.基本概念 Task优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便,例

  • C#中的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 DoRunTaskAs

  • C#中的Task.WhenAll和Task.WhenAny方法介绍

    一.简介 Task.WhenAll().Task.WhenAny()这两个与Task.WaitALL().Task.WaitAny()是有区别的,When是异步的,Wait是同步的.Task.WhenAll():所有提供的任务已完成时,创建将完成的任务.Task.WhenAny():任何提供的任务已完成时,创建将完成的任务. 二.代码案例 Task.WhenAll 代码: class Program { public class DownLoadTest { Stopwatch watch =

  • Java中获取键盘输入值的三种方法介绍

    程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代表遇到这种情况我们就束手无策,请你看以下三种解决方法吧: 以下将列出几种方法: 方法一:从控制台接收一个字符,然后将其打印出来 public static void main(String [] args) throws IOException{ System.out.print("Enter a char

  • python中Flask Web 表单的使用方法介绍

    目录 简介 普通表单提交 Flask-WTF基础 使用Flask-WTF处理表单 Flask消息闪现 文件上传 文件上传的另一种写法 简介 表单的操作是Web程序开发中最核心的模块之一,绝大多数的动态交互功能都是通过表单的形式实现的.本文会教大家实现简单的表单操作. 普通表单提交 在创建模板login.html页面中直接写form表单. login.html <!DOCTYPE html> <html lang="en"> <head>    <

  • perl中srand()与time的函数使用方法介绍

    在perl中srand()提供供rand()使用的随机数种子,rand()产生随机数生成器.如果在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand().使用同种子相同的数调用srand()会导致相同的随机数序列被生成. 举例如下: 复制代码 代码如下: srand(26);  $number1=rand(100);  print "$number1\n";  srand(26);  $number2=rand(100);  print "$n

  • Python中list列表的一些进阶使用方法介绍

    判断一个 list 是否为空 传统的方式: if len(mylist): # Do something with my list else: # The list is empty 由于一个空 list 本身等同于 False,所以可以直接: if mylist: # Do something with my list else: # The list is empty 遍历 list 的同时获取索引 传统的方式: i = 0 for element in mylist: # Do somet

  • Python中条件选择和循环语句使用方法介绍

    同C语言.Java一样,Python中也存在条件选择和循环语句,其风格和C语言.java的很类似,但是在写法和用法上还是有一些区别.今天就让我们一起来了解一下. 一.条件选择语句 Python中条件选择语句的关键字为:if .elif .else这三个.其基本形式如下: 复制代码 代码如下: if condition: block elif condition: block ... else block 其中elif和else语句块是可选的.对于if和elif只有condition为True时,

  • JavaScript中检查对象property的存在性方法介绍

    在JavaScript中,可以用四种方法来检查某个对象o是否拥有property x: 1."x" in o.in操作符可用于检查对象o中是否有x这个property.x可以是对象自身的(Own Property),也可以是从原型对象中继承而来的:x可以是enumerable的property,也可以是非enumerable的property. 2.o.x.可以通过访问o.x语句,判断其结果是否为undefined来确认x是否存在,其作用范围与in操作符相同.与in操作符不同的是:如果

  • PowerShell中Get-Date对象的常用属性和方法介绍

    本文介绍PowerShell中使用Get-Date得到的日期对象的属性和方法,利用好这些对象和方法,可以极大的增强我们开发的灵活性. 使用Get-Date可以获取到一个时间对象,这个时间对象,可不是仅仅用来输出当前时间这么简单.我们来看看它的属性和方法吧,不看白不看. 要想看一个对象的成员(即对象的属性和方法),可以使用管道符,再加上Get-Member这个cmdlet.很方便滴! 复制代码 代码如下: PS C:\Users\zhanghong> Get-Date | Get-Member T

  • JavaScript中对象property的读取和写入方法介绍

    JavaScript中,可以通过点号操作符"."或者中括号操作符"[]"来对对象的property进行读取和写入: 复制代码 代码如下: var o = {x:1, y:2}; console.log(o.x);//1 console.log(o["y"]);//2 o.y = 7; console.log(o["y"]);//7 值得注意的是,如果使用中括号操作符,则操作符内的值类型必须是string,或者能够转换成stri

  • JavaScript中数组对象的那些自带方法介绍

    /** * 本文纯粹是梳理一下目前W3C标准中Array对象的自带Method. * 全文没啥营养,不过最后性能测试的部分,倒是抛出了一些疑问. */ 赋值方法 (Mutator methods) 这些方法直接修改数组自身 pop 和 push Array.pop(); // 删除数组最后一个元素,返回被删除的元素 Array.push(element1, ..., elementN); // 在数组尾部插入1-N个元素,返回操作后数组的length 通过这 pop 和 push ,就能把数组模

随机推荐