• 使用任务并行库-组合任务


      本节将展示如何设置相互依赖的任务。我们将学习如何创建一个任务,使其在父任务完成后才会被运行。另外,将探寻为非常短暂的任务节省线程开销的可能性。

    class Program
    {
        static void Main(string[] args)
        {
            var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
            var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));
     
            firstTask.ContinueWith(//给第一个任务设置后续操作,在第一个任务完成后执行
                t => Console.WriteLine("The first answer is {0}. Thread id {1}, is thread pool thread: {2}",
                    t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
                TaskContinuationOptions.OnlyOnRanToCompletion);
     
            firstTask.Start();
            secondTask.Start();
     
            Thread.Sleep(TimeSpan.FromSeconds(4));//主线程----等待上面两个任务的完成,4秒应该足够执行完上面2个操作
         //如果注释掉以上语句,主线程直接执行下面的语句,则第二个任务的后续操作会放到线程池中执行

    /* 设置第二个任务的后续操作,TaskContinuationOptions.ExecuteSynchronously设置为同步执行,
    * 如果上面不等待4秒,后续操作将放到线程池中等待第二个任务执行完成后执行;如果等待4秒,即等待
    * 第二个任务的完成,则后续操作被放到主线程中执行。因为后续操作非常短暂,所以放到主线程中比放到
    * 线程池中运行快。
    * TaskContinuationOptions.OnlyOnRanToCompletion指示第二个任务完成后才会安排后续任务。
    */

            Task continuation = secondTask.ContinueWith(//第二个任务运行另一个后续操作
                t => Console.WriteLine("The second answer is {0}. Thread id {1}, is thread pool thread: {2}",
                    t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
                TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
     
            continuation.GetAwaiter().OnCompleted(//给continuation任务继续安排后续任务
                () => Console.WriteLine("Continuation Task Completed! Thread id {0}, is thread pool thread: {1}",
                    Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
     
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine();
     
        //以下为父子任务线程有关
        /* 子任务必须在父任务运行时创建,并且正确的附加给父任务!
        * TaskContinuationOptions.AttachedToParent把子任务添加到父任务,只有所有子任务都完成,父任务才能完成。
        */
    firstTask
    = new Task<int>(() =>//创建新任务 {
           //通过提供AttachedToParent选项来来运行一个所谓的子任务
    var innerTask = Task.Factory.StartNew(() => TaskMethod("Second Task", 5), TaskCreationOptions.AttachedToParent); innerTask.ContinueWith(t => TaskMethod("Third Task", 2), TaskContinuationOptions.AttachedToParent); return TaskMethod("First Task", 2); }); firstTask.Start();     //以下语句可以验证父任务是否在子任务全部结束后完成 while (!firstTask.IsCompleted) { Console.WriteLine(firstTask.Status); Thread.Sleep(TimeSpan.FromSeconds(0.5)); } Console.WriteLine(firstTask.Status); Thread.Sleep(TimeSpan.FromSeconds(10)); } static int TaskMethod(string name, int seconds) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds)); return 42 * seconds; } }
  • 相关阅读:
    使用Redis的理由
    从输入网址到显示网页的全过程分析
    Node.js初识
    GET和POST的数据传递到底有何区别?
    第四五六周学习进度
    首尾相接整数数组中最大子数组的和
    网页版四则运算
    团队介绍及项目简介
    整数数组中最大子数组的和
    软件工程个人作业03
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12610287.html
Copyright © 2020-2023  润新知