zoukankan      html  css  js  c++  java
  • Task的一些用法总结

    一、Task和多线程以及异常的捕获示例代码:

    static void Main(string[] args)
            {
                // 产生CancellationToken的类,该类允许使用Cancel方法终止线程
                // 也可以使用CancellationTokenSource.CreateLinkedTokenSource创建
                // 一组相关的Token,任意一个取消都取消
                CancellationTokenSource ts = new CancellationTokenSource();
                
                CancellationToken ct = ts.Token;
    
                Task t = null;
    
                t = new Task(() =>
                              {
                                  for (int i = 1; i < 11; i++)
                                  {
                                      // 调用Cancel方法,状态为true(表示已经取消了)
                                      if (!ts.IsCancellationRequested)
                                      {
                                          if (i == 5)
                                          {
                                              // 该异常不会直接被主线程捕获
                                              throw new Exception("数字是5,非法!");
                                          }
                                      }
                                      else
                                      {
                                          Console.WriteLine("用户取消");
                                          // 抛出异常,强制取消子线程
                                          ct.ThrowIfCancellationRequested();
                                      }
                                      Console.WriteLine(i);
                                      Thread.Sleep(500);
                                  }
                              }, ct);
                t.Start();
    
                // 注册Cancel之后的引发的事件,注意Exception也可以在这里捕获
                t.ContinueWith((task) =>
                {
                    // 只有调用Cancel方法才会被设置为True
                    Console.WriteLine(t.IsCanceled);
                    // 无论何种情况,只要完成了就是True
                    Console.WriteLine(t.IsCompleted);
                    // 只要有异常,为True(哪怕是ThrowIfCancellationRequested异常)
                    Console.WriteLine(t.IsFaulted);
                    // 捕获各种各样的异常
                    foreach (var item in task.Exception.InnerExceptions)
                    {
                        Console.WriteLine(item.Message);
                    }
                });
                Console.ReadLine();
                // 取消任务
                ts.Cancel();
                Thread.Sleep(Timeout.Infinite);
            }

    结论:

    1、无论任何异常都会终止子线程。

    2、异常发生之后,只有在Task的Wait/WaitAll/WaitAny/Result或者Continue方法才可以捕获异常,主线程不可能,因为是子线程中的异常。

    二、Task的任务先后顺序(允许嵌套任务),同时允许把线程挂接到主线程上执行返回结果(避免以前Thread和WinForm控件交互时候发生的“不是由本线程创建的控件异常……”问题):

    static void Main(string[] args)
            {
                CancellationTokenSource cts = new CancellationTokenSource();
                CancellationToken ct = cts.Token;
    
                Task t = new Task(() =>
                {
                    Console.WriteLine("主任务开始……,包含3个子任务:");
                    Task.Factory.StartNew(() =>
                    {
                        Thread.Sleep(2000);
                        Console.WriteLine("任务一");
                    },
                        // 挂接到主线程,这样主线程会自动等待子线程完成后完成
                        TaskCreationOptions.AttachedToParent );
    
                    Task.Factory.StartNew(() =>
                    {
                        Thread.Sleep(500);
                        Console.WriteLine("任务二");
                    }, TaskCreationOptions.AttachedToParent);
    
                    Task.Factory.StartNew(() =>
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine("任务三");
                    },
                        TaskCreationOptions.AttachedToParent);
                }, ct);
    
    
                t.ContinueWith((Task) =>
                {
                    Console.WriteLine("子任务都完成,主任务结束。");
                    // 指定上下文的同步块,防止跨线程访问控件的问题(控制台程序不能使用,WinForm啥可以)
                },TaskScheduler.FromCurrentSynchronizationContext());
                t.Start();
    
                Thread.Sleep(Timeout.Infinite);
            }

    相比较原来的Wait而言,不会卡死子线程,而且又可以多任务运行。

    欲想知道更多关于线程操作的东西,可以参考:

    MSDN,并行处理系列篇:http://msdn.microsoft.com/zh-cn/library/vstudio/3e8s7xdd(v=vs.110).aspx

  • 相关阅读:
    男人应该懂得的
    喝酒礼仪
    Office Web Apps开放测试
    SAP系统概要
    SAP实施成功的关键因素
    SAP企业实施的方法论
    ASAP
    ERP系统的组成部分
    去除word的保护
    实习周小结
  • 原文地址:https://www.cnblogs.com/ServiceboyNew/p/4216346.html
Copyright © 2011-2022 走看看