Task——等待任务完成并获取结果

作者:追风剑情 发布于:2017-10-1 12:38 分类:C#

示例: task.Wait()的使用

  1. using System;
  2. using System.Threading.Tasks;
  3.  
  4. namespace TastTest
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. //处理Task中未观察到的异常,默认情况下会结束进程。
  11. //每次当一个Task被垃圾回收时,如果存在一个没有被注意到的异常,CLR
  12. //的终结器线程就会引发这个事件。一旦引发,就会向你的事件处理方法传递
  13. //一个UnobservedTaskExceptionEventArgs对象,其中包含你没有注意到的
  14. //AggregateException
  15. TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
  16.  
  17. // 创建一个Task(现在还没开始运行)
  18. Task<Int32> t = new Task<Int32>(n=>Sum((Int32)n), 1000000000);
  19. // 可以稍后再启动任务
  20. t.Start();
  21. // 可选择显式等待任务完成
  22. // 注意:还有一些重载版本能接受timeout/CancellationToken值
  23. t.Wait();
  24. // 可获得结果(Result属性内部会调用Wait)
  25. Console.WriteLine("The Sum is: "+t.Result);//一个Int32值
  26.  
  27. Console.ReadLine();
  28. }
  29.  
  30. private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
  31. {
  32. //显示异常堆栈信息
  33. Console.WriteLine(e.Exception.StackTrace);
  34. //标记为“已观察到”,这样将阻止该异常触发默认情况下会终止进程的异常升级策略。
  35. e.SetObserved();
  36. }
  37.  
  38. private static Int32 Sum(Int32 n)
  39. {
  40. Int32 sum = 0;
  41. for (; n > 0; n--)
  42. {
  43. try
  44. {
  45. //checked()或checked{}用来检查算术运算是否溢出
  46. //并抛出异常
  47. //这里如果n太大,会抛出System.OverflowException
  48. checked { sum += n; }
  49. }
  50. catch (OverflowException e)
  51. {
  52. Console.WriteLine("Int32 sum溢出了");
  53. }
  54. }
  55. return sum;
  56. }
  57. }
  58. }


重要提示 线程调用Wait方法时,系统检查线程要等待的Task是否已开始执行。如果是,调用Wait的线程会阻塞,直到Task运行结束为止。但如果Task还没开始执行,系统可能(取决于TaskScheduler)使用调用Wait的线程来执行Task。在这种情况下,调用Wait的线程不会阻塞;它会执行Task并立即返回。好处在于,没有线程会被阻塞,所以减少了对资源的占用(因为不需要创建一个线程来替代被阻塞的线程),并提升了性能(因为不需要花时间创建线程,也没有上下文切换)。不好的地方在于,假如线程在调用Wait前已获得了一个线程同步锁,而Task试图获取同一个锁,就会造成死锁的线程


运行测试

11111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号