zoukankan      html  css  js  c++  java
  • C# Task 的用法

    C# Task 的用法(转自:http://www.wxzzz.com/683.html#)

    其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观。代码更简洁了,使用Task来进行操作。可以跟线程一样可以轻松的对执行的方法进行控制。

    顺便提一下,配合CancellationTokenSource类更为可以轻松的对Task操作的代码进行中途终止运行,会在后面的章节中讲述。

    如果我们使用线程池来实现某几个方法运行,然后等待运行完成的大概会编写如下代码:

    1. using (ManualResetEvent m1 = new ManualResetEvent(false))
    2. using (ManualResetEvent m2 = new ManualResetEvent(false))
    3. {
    4.     ThreadPool.QueueUserWorkItem(delegate
    5.     {
    6.         MyMethodA();
    7.         m1.Set();
    8.     });
    9.     ThreadPool.QueueUserWorkItem(delegate
    10.     {
    11.         MyMethodB();
    12.         m2.Set();
    13.     });
    14.     WaitHandle.WaitAll(new WaitHandle[] { m1, m2, });
    15. }

    如果用Task类的话,相对就比较简单了,至少代码看起来很舒服。也就意味着维护也比较方便

    1. Task t1 = Task.Factory.StartNew(delegate { MyMethodA(); });
    2. Task t2 = Task.Factory.StartNew(delegate { MyMethodB(); });
    3. t1.Wait();
    4. t2.Wait();

    上面的方法是一个一个的执行完毕,获取不是我们想要的,我们一般是想要他们一起同时执行,提高程序处理事情的效率。

    1. Task t1 = Task.Factory.StartNew(delegate { MyMethodA(); });
    2. Task t2 = Task.Factory.StartNew(delegate { MyMethodB(); });
    3. Task.WaitAll(t1, t2);

    下面我们来简单介绍下Task的用法

    创建 Task

    创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建。如下代码所示

    1.使用构造函数创建Task

    1.  Task t1 = new Task(MyMethod);

    2.使用Task.Factory.StartNew 进行创建Task

    1.  Task t1 = Task.Factory.StartNew(MyMethod);

    其实这两种方式都是一样的,Task.Factory 是对Task进行管理,调度管理这一类的。好学的伙伴们,可以深入研究。这不是本文的范畴,也许会在后面的文章细说。

    运行 Task

    运行Task的两种方式,在上面我们已经提到过了,一种等待运行完毕,另一种则等待所有运行完毕。不过这里还有一种就是异步运行,跟使用多线程一样,调用Task对象中的Start()方法即可。看看下面这个控制台示例。纯粹是Wait和AllWait的话,仅仅是等待。而不是执行。所以我们还需要调用Start()方法

    1. static void Main(string[] args)
    2. {
    3.     Task t1 = new Task(MyMethod);
    4.     t1.Start();
    5.     Console.WriteLine("主线程代码运行结束");
    6.     Console.ReadLine();
    7. }
    8.  
    9. static void MyMethod()
    10. {
    11.     for (int i = 0; i < 5; i++)
    12.     {
    13.         Console.WriteLine(DateTime.Now.ToString());
    14.         Thread.Sleep(1000);
    15.     }
    16. }

    运行效果如图

    Task因为我们没有调用Wait 所以是异步执行的~

    取消Task

    我们一开始就描述了 CancellationTokenSource 这个对象对Task的取消运行。一般是用不到这个方法的,一般会正常的退出所运行的代码,如使用 bool IsExit 之类的来进行一个控制。而不是中途强制中断代码。

    可以参考我的这篇文章:http://www.wxzzz.com/643.html

    至于 CancellationTokenSource 控制Task,下一篇文章会进行详细的一个介绍。

    Task的异常处理

    因为Task中是异步执行,你也可以理解为跟多线程一样,具体错误捕获需要自己去捕获。很有意思的是Task的异常还会重新抛到Wait和AllWait中,我们可以进行方便的捕获这些异常。如下代码

    1. static void Main(string[] args)
    2. {
    3.     Task t1 = new Task(MyMethod);
    4.     t1.Start();
    5.     t1.Wait();
    6.     Console.WriteLine("主线程代码运行结束");
    7.     Console.ReadLine();
    8. }
    9.  
    10. static void MyMethod()
    11. {
    12.     throw new Exception("Task异常测试");
    13. }

    运行效果如图

    Task Exception

    获取 Task 的返回值

    先看看代码

    1. Task<string> t1 = Task.Factory.StartNew(() => "测试");
    2. t1.Wait();
    3. Console.WriteLine(t1.Result);
    4. Console.ReadLine();

    返回值可以是任意的类型,因为是个泛型嘛~ 还是依然的非常简洁的代码。

    至此,就是 C# Task 的相关用法了,欢迎回复讨论。

  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/wjcnet/p/6955756.html
Copyright © 2011-2022 走看看