在 .Net 开发中, 使用 Task 、 Task<T> 进行异步编程是非常方便的, 但是在处理 Task 产生的异常时, 需要注意一个问题, 比如下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
static Task<int> TestAsync(int a, int b) {
   var tcs = new TaskCompletionSource<int>();
   Task.Factory.StartNew(() => {
      if (a + b < 0) {
         tcs.TrySetException(new InvalidOperationException("a + b < 0"));
      }
      else {
         tcs.TrySetResult(a + b);
      }
   });
   return tcs.Task;
}

当输入的两个参数之和小于 0 时, tcs 会设置一个 InvalidOperationException , 如果直接运行这段代码, 当这个函数返回的 Task 被 GC 回收时, 将会产生 AggregateException was unhandled 的异常, 运行代码如下:

1
2
3
4
5
6
7
8
9
10
static void Main(string[] args) {
 
   TestAsync(5, -10);
 
   Thread.Sleep(TimeSpan.FromMilliseconds(3000));
 
   GC.Collect();
 
   Console.WriteLine("Completed.");
}

当程序运行结束时, 会产生下图所示的异常:

关键的是这段文字:

A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.

没有在等待 Task 完成时捕获其异常, 也没有读取 Task 的 Exception 属性, 结果导致异常被终结线程重新抛出。 也就是说, Task 异常有两种处理方式:

1、 调用 Task 的 Wait 方法时使用 try-catch 捕获异常:

1
2
3
4
5
6
7
var testTask = TestAsync(5, -10);
try {
   testTask.Wait();
}
catch(Exception ex) {
   Console.WriteLine(ex);
}

2、 在 Task 的 ContinueWith 方法中读取 Task 的 Exception 属性:

1
2
3
4
5
6
7
8
9
var testTask = TestAsync(5, -10);
testTask.ContinueWith(task => {
   if (task.IsFaulted) {
      Console.WriteLine(task.Exception.GetBaseException());
   }
   else {
      Console.WriteLine(task.Result);
   }
});

在 .Net 4.0 、 Sliverlight 5.0 、以及 MonoTouch 中均有类似的问题, 因此, 必须小心翼翼的处理 Task 产生的异常, 否则将会导致你的程序异常退出。

张志敏所有文章遵循创作共用版权协议,要求署名、非商业 、保持一致。在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处。

Task 编程中的异常处理的更多相关文章

  1. T-SQL编程中的异常处理-异常捕获(catch)与抛出异常(throw)

    本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出,本文简单介绍异常捕获与异 ...

  2. T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)

    本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出(try catch th ...

  3. Java 编程中关于异常处理的 10 个最佳实践

    异常处理是Java 开发中的一个重要部分.它是关乎每个应用的一个非功能性需求,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等.Java提供了几个异常处理特性,以try,catch 和 ...

  4. 【转】Java中关于异常处理的十个最佳实践

    原文地址:http://www.searchsoa.com.cn/showcontent_71960.htm 导读:异常处理是书写强健Java应用的一个重要部分,Java许你创建新的异常,并通过使用 ...

  5. 编写高质量代码改善C#程序的157个建议——建议85:Task中的异常处理

    建议85:Task中的异常处理 在任何时候,异常处理都是非常重要的一个环节.多线程与并行编程中尤其是这样.如果不处理这些后台任务中的异常,应用程序将会莫名其妙的退出.处理那些不是主线程(如果是窗体程序 ...

  6. C#中async/await中的异常处理

    在同步编程中,一旦出现错误就会抛出异常,我们可以使用try-catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...

  7. 关于C#中async/await中的异常处理(上)-(转载)

    在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...

  8. 【转】C# Async/Await 异步编程中的最佳做法

    Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...

  9. 关于C#中async/await中的异常处理(上)

    关于C#中async/await中的异常处理(上) 2012-04-11 09:15 by 老赵, 17919 visits 在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕 ...

随机推荐

  1. shell命令一行代码搞定【转】

    查看文件内容-while: cat 1.txt|while read line;do echo $line;done while read line; do echo $line; done < ...

  2. "Debugging not possible in single session mode"

    PLSQL  Developer在测试存储过程,遇到"Debugging not possible in single session mode" 解决办法: 点击菜单栏" ...

  3. passwd总结

    1.当前用户是root root用户修改密码 ,直接 passwd[不要输入当前用户密码] 如果修改其他用户密码,需要 passwd 用户名 如: passwd sc 短短的密码,如123也能通过,因 ...

  4. FreeRTOS中断优先级配置(重要)

    FreeRTOS中断优先级配置(重要) 本章节为大家讲解FreeRTOS中断优先级配置,此章节非常重要,初学者经常在这里犯迷糊.对于初学者来说,本章节务必要整明白.12.1 NVIC基础知识12.2  ...

  5. sed用法小结

    简介: sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区 ...

  6. oracle一次删除多张表

    通过拼接sql语句来完成 例如有如下个表 想一次性删除,执行如下语句: select 'drop table '||table_name ||';' as dropsql from USER_TABL ...

  7. Too Much Money

    Too Much Money time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  8. SEO策略与细节:细节决定成败

    昨天展开seo探讨会.听了一场医疗界seo大神的讲座.收益匪浅今天讲他的演讲内容整理出来与大家分享.希望对医疗界的seo带来些帮助.站长们一起成长! 一.首页 1.元标签设置 标题:上海癫痫病医院哪家 ...

  9. IMP指针

    可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数看起来. Method Swizzling 如果对Runtime有一定了解的 ...

  10. Android ViewDragHelper完全解析 自定义ViewGroup神器

    Android ViewDragHelper完全解析 自定义ViewGroup神器   转载请标明出处: http://blog.csdn.net/lmj623565791/article/detai ...