改善C#程序的157个建议(连载80)

发表于:2011-11-28 09:27

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陆敏技    来源:51Testing软件测试网采编

  建议80:用Task代替ThreadPool

  ThreadPool相对于Thread来说具有很多优势,但是ThreadPool在使用上却存在一定的不方便。比如:

  ThreadPool不支持线程的取消、完成、失败通知等交互性操作。

  ThreadPool不支持线程执行的先后次序。

  以往,如果开发者要实现上述功能,需要完成很多额外的工作。现在,FCL中提供了一个功能更强大的概念:Task。Task在线程池的基础上进行了优化,并提供了更多的API。在FCL 4.0中,如果我们要编写多线程程序,Task显然已经优于传统的方式了。

  以下是一个简单的任务示例:

  • static void Main(string[] args)  
  • {  
  •     Task t = new Task(() => 
  •         {  
  •             Console.WriteLine("任务开始工作……");  
  •             //模拟工作过程  
  •             Thread.Sleep(5000);  
  •         });  
  •     t.Start();  
  •     t.ContinueWith((task) => 
  •         {  
  •             Console.WriteLine("任务完成,完成时候的状态为:");  
  •             Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}",  
  •      task.IsCanceled, task.IsCompleted, task.IsFaulted);  
  •         });  
  •     Console.ReadKey();  
  • }
  •   任务Task具备以下属性,可以让我们查询任务完成时的状态:

  • IsCanceled  因为被取消而完成  
  • IsCompleted 成功完成  
  • IsFaulted       因为发生异常而完成
  •   需要注意的是,任务并没有提供回调事件来通知完成(像BackgroundWorker一样),它是通过启用一个新任务的方式来完成类似的功能。ContinueWith方法可以在一个任务完成的时候发起一个新任务,这种方式天然就支持了任务的完成通知:我们可以在新任务中获取原任务的结果值。

      下面是一个稍微复杂的例子,同时支持完成通知、取消、获取任务返回值等功能:

  • static void Main(string[] args)  
  • {  
  •     CancellationTokenSource cts = new CancellationTokenSource();  
  •     Task<int> t = new Task<int>(() => Add(cts.Token), cts.Token);  
  •     t.Start();  
  •     t.ContinueWith(TaskEnded);  
  •     //等待按任意键取消任务  
  •     Console.ReadKey();  
  •     cts.Cancel();  
  •     Console.ReadKey();  
  • }  
  • static void TaskEnded(Task<int> task)  
  • {  
  •     Console.WriteLine("任务完成,完成时候的状态为:");  
  •     Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}",  
  •         task.IsCanceled, task.IsCompleted, task.IsFaulted);  
  •     Console.WriteLine("任务的返回值为:{0}", task.Result);  
  • }  
  • static int Add(CancellationToken ct)  
  • {  
  •     Console.WriteLine("任务开始……");  
  •     int result = 0;  
  •     while (!ct.IsCancellationRequested)  
  •     {  
  •         result++;  
  •         Thread.Sleep(1000);  
  •     }  
  •     return result;  
  • }
  •   在任务开始后大概3秒的时候按下键盘,会得到如下的输出:

    任务开始……

      任务完成,完成时候的状态为:

  • IsCanceled=False        IsCompleted=True        IsFaulted=False 
  • 任务的返回值为:3
  • 31/3123>
    《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号