Task 编程中的异常处理
在 .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 编程中的异常处理的更多相关文章
- T-SQL编程中的异常处理-异常捕获(catch)与抛出异常(throw)
本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出,本文简单介绍异常捕获与异 ...
- T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)
本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出(try catch th ...
- Java 编程中关于异常处理的 10 个最佳实践
异常处理是Java 开发中的一个重要部分.它是关乎每个应用的一个非功能性需求,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等.Java提供了几个异常处理特性,以try,catch 和 ...
- 【转】Java中关于异常处理的十个最佳实践
原文地址:http://www.searchsoa.com.cn/showcontent_71960.htm 导读:异常处理是书写强健Java应用的一个重要部分,Java许你创建新的异常,并通过使用 ...
- 编写高质量代码改善C#程序的157个建议——建议85:Task中的异常处理
建议85:Task中的异常处理 在任何时候,异常处理都是非常重要的一个环节.多线程与并行编程中尤其是这样.如果不处理这些后台任务中的异常,应用程序将会莫名其妙的退出.处理那些不是主线程(如果是窗体程序 ...
- C#中async/await中的异常处理
在同步编程中,一旦出现错误就会抛出异常,我们可以使用try-catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...
- 关于C#中async/await中的异常处理(上)-(转载)
在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...
- 【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
- 关于C#中async/await中的异常处理(上)
关于C#中async/await中的异常处理(上) 2012-04-11 09:15 by 老赵, 17919 visits 在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕 ...
随机推荐
- linuxmint计算器
命令行输入bc进入计算器, 可以计算 + 加法 - 减法* 乘法 / 除法^ 指数 % 余数 quit 关闭计算器
- 把perl脚本编译成exe
来源:http://www.veryhuo.com/a/view/38338.html 今天想把 perl 脚本编译成 exe 以便脱离 perl 解释器独立运行.都可以生成PERL的PE文件,在PE ...
- Git中的merge命令实现中出现问题及其解决
Git中的merge命令实现和工作方式 2015年8月17日星期一 丹丹 git代码在合并两个分支的时候总是会出现一下的错误提示,不能正常的完成合并分支,错误提示如图所示: 但是在其他的终端是可以完成 ...
- HttpCookie类
转自:http://www.cnblogs.com/kissdodog/archive/2013/01/08/2851937.html HttpCookie类专门由C#用于读取和写入Cookie的类. ...
- vs2010在进行数据架构比较时报'text lines should not be null'错误
通过VS2010进行服务器数据库和本地数据库比较架构(都是sql server 2008 R2)时,弹出“text lines should be not null”错误,如下图: 解决方法:在Vis ...
- innerHTML,innerText,outerHTML,outerText,value浅析
首先是一个例子: <div id= "aa">0<br/>0<span>11</span>22</div><inp ...
- 字符串查找 cmd find命令
find /i "ora-" *.log 我对findstr是如此的依赖,以至于当我向各位讲解find命令的时候,我还得老老实实地在cmd窗口中敲下 find /? 这条命令,然后 ...
- UVA106 - Fermat vs. Pythagoras
假设x为奇数,y为偶数,则z为奇数,2z与2x的最大公因数为2,2z和2x可分别写作 2z = (z + x) + (z - x) 2x = (z + x) - (z - x) 那么跟据最大公因数性质 ...
- iOS 常用代码块
1.判断邮箱格式是否正确的代码: // 利用正则表达式验证 -( BOOL )isValidateEmail:( NSString *)email { NSString *emailRegex ...
- Node.js学习 - File Operation
同步异步 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync(). 异步的方法函数最后一个参数为 ...