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;
            });

            //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
            task.Start();
            Console.WriteLine("主線程執行其他程序.");

            //任务完成时执行处理。
            Task cwt = task.ContinueWith(t =>
            {
                Console.WriteLine("任務完成後的結果是:{0}", t.Result.ToString());
            });
            task.Wait();
            cwt.Wait();
            Console.ReadLine();
            Console.ReadKey();
        }

结果:

任务的串行

代码:

        static void Main(string[] args)
        {
            ConcurrentStack<int> stack = new ConcurrentStack<int>();

            //t1先串行
            var t1 = Task.Factory.StartNew(() =>
            {
                //入棧
                stack.Push(1);
                stack.Push(2);
            });

            //t2,t3并行执行
            var t2 = t1.ContinueWith(t =>
            {
                int result;
                //出棧
                stack.TryPop(out result);
                Console.WriteLine("Task t2 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
            });

            //t2,t3并行执行
            var t3 = t1.ContinueWith(t =>
            {
                int result;
                //出棧
                stack.TryPop(out result);
                Console.WriteLine("Task t3 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
            });

            //等待t2和t3执行完
            Task.WaitAll(t2, t3);

            //t7串行执行
            var t4 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("當前的集合數目:{0},Thread id {1}", stack.Count, Thread.CurrentThread.ManagedThreadId);
            });
            t4.Wait();
            Console.ReadKey();
        }

结果:

子任务

代码:

        public static void Main()
        {
            Task<string[]> parent = new Task<string[]>(state =>
            {
                Console.WriteLine(state);
                string[] result = new string[2];
                //创建并启动子任务
                new Task(() => { result[0] = "我是子任務1。"; }, TaskCreationOptions.AttachedToParent).Start();
                new Task(() => { result[1] = "我是子任務2。"; }, TaskCreationOptions.AttachedToParent).Start();
                return result;
            }, "我是父任務,並在處理過程中創建多個子任務,所有的子任務完成以後我才會開始執行。");
            //任务处理完成后执行的操作
            parent.ContinueWith(t =>
            {
                Array.ForEach(t.Result, r => Console.WriteLine(r));
            });
            //启动父任务
            parent.Start();
            //等待任务结束 Wait只能等待父线程结束,没办法等到父线程的ContinueWith结束
            //parent.Wait();
            Console.ReadLine();
        }

结果:

动态并行

代码:

    class Node
    {
        public Node Left { get; set; }
        public Node Right { get; set; }
        public string Text { get; set; }
    }
    class Program
    {
        static Node GetNode()
        {
            Node root = new Node
            {
                Left = new Node
                {
                    Left = new Node
                    {
                        Text = "L-L"
                    },
                    Right = new Node
                    {
                        Text = "L-R"
                    },
                    Text = "L"
                },
                Right = new Node
                {
                    Left = new Node
                    {
                        Text = "R-L"
                    },
                    Right = new Node
                    {
                        Text = "R-R"
                    },
                    Text = "R"
                },
                Text = "Root"
            };
            return root;
        }

        static void Main(string[] args)
        {
            Node root = GetNode();
            DisplayTree(root);
        }

        static void DisplayTree(Node root)
        {
            var task = Task.Factory.StartNew(() => DisplayNode(root),
                                            CancellationToken.None,
                                            TaskCreationOptions.None,
                                            TaskScheduler.Default);
            task.Wait();
        }

        static void DisplayNode(Node current)
        {

            if (current.Left != null)
                Task.Factory.StartNew(() => DisplayNode(current.Left),
                                            CancellationToken.None,
                                            TaskCreationOptions.AttachedToParent,
                                            TaskScheduler.Default);
            if (current.Right != null)
                Task.Factory.StartNew(() => DisplayNode(current.Right),
                                            CancellationToken.None,
                                            TaskCreationOptions.AttachedToParent,
                                            TaskScheduler.Default);
            Console.WriteLine("當前節點值:{0};處理的Thread ID ={1}", current.Text, Thread.CurrentThread.ManagedThreadId);
        }
    }

结果:

到此这篇关于C#使用Task.ContinueWith组合任务的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C# 并行和多线程编程——Task进阶知识

    一.Task的嵌套 Task中还可以再嵌套Task,Thread中能不能这样做,我只能说我是没这样写过.Task中的嵌套,我感觉其实也可以分开来写,不过嵌套起来会方便管理一点.Task中的嵌套分为两种,关联嵌套和非关联嵌套,就是说内层的Task和外层的Task是否有联系,下面我们编写代码先来看一下非关联嵌套,及内层Task和外层Task没有任何关系,还是在控制台程序下面,代码如下: static void Main(string[] args) { var pTask = Task.Factor

  • C#异步方法返回void与Task的区别详解

    C#异步方法返回void和Task的区别 如果异步(async关键字)方法有返回值,返回类型为T时,返回类型必然是 Task<T>. 但是如果没有返回值,异步方法的返回类型有2种,一个是返回 Task, 一个是返回 void: public async Task CountDownAsync(int count) { for (int i = count; i >= 0; i--) { await Task.Delay(1000); } } public async void Count

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

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

  • 详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿

    说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行:等到后台线程执行完毕,再通知主线程,然后做出对应操作! 在C#中开启新线程比较简单 static void Main(string[]

  • C# 并行和多线程编程——认识和使用Task

    对于多线程,我们经常使用的是Thread.在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于"任务的编程模型"所冲击,因为task会比thread具有更小的性能开销,不过大家肯定会有疑惑,任务和线程到底有什么区别呢? 任务和线程的区别: 1.任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行. 2.任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线

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

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

  • C#利用Task实现任务超时多任务一起执行的方法

    前言 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建. 如下代码所示 1.使用构造函数创建Task Task t1 = new Task(MyMethod); 2.使用Task.Factory.StartNew 进行创建Task Task t1 = Task.Fact

  • 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应用实例详解

    Task的应用 ​Task的MSDN的描述如下: [Task类的表示单个操作不会返回一个值,通常以异步方式执行. Task对象是一种的中心思想基于任务的异步模式首次引入.NETFramework 4 中. 因为由执行工作Task对象通常以异步方式执行线程池线程上而不是以同步方式在主应用程序线程中,可以使用Status属性,并将IsCanceled, IsCompleted,和IsFaulted属性,以确定任务的状态. 大多数情况下,lambda 表达式用于指定该任务所执行的工作量. 对于返回值的

  • 深入分析C# Task

    ​Task的MSDN的描述如下: [Task类的表示单个操作不会返回一个值,通常以异步方式执行. Task对象是一种的中心思想基于任务的异步模式首次引入.NETFramework 4 中. 因为由执行工作Task对象通常以异步方式执行线程池线程上而不是以同步方式在主应用程序线程中,可以使用Status属性,并将IsCanceled, IsCompleted,和IsFaulted属性,以确定任务的状态. 大多数情况下,lambda 表达式用于指定该任务所执行的工作量. 对于返回值的操作,您使用Ta

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

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

随机推荐