Task异常捕获的方式
这节来讲一下如果捕获Task的异常。
当Task运行中出现了异常,正常情况下我们在主线程的Try是捕获不到的,而如果在Task内部写try,出现了异常我们会完全不知道。下面就来介绍几个主线程捕获Task异常的方法。
阻塞线程式
我们可以使用Wait(),WaitAny(),WaitAll()来捕获Task的异常,详见下图:

捕获Task异常,准确来说要用AggregateException类,右边是运行结果,成功捕获到了异常信息,其它两个等待也是类似的用法,不熟悉的小伙伴可以参见前文:等待多个异步任务的方法。
在等待多个Task异常时,可以访问异常对象的InnerExceptions属性来遍历所有的异常:

上述异常捕获的解决方案,因为涉及到了等待,所以会阻塞主线程,并且如果异常发生在等待之前,同样是不能捕获到,所以这种方式,虽然简单,但是使用场景并不多。
异步式
我们知道Task有个ContinueWith方法,它会在Task完成后继续异步执行传入的委托,我们可以通过这个方法实现异常捕获,请看如下代码:

因为是异步执行,所以这样不会阻塞主线程。
事件式
事件式的思路是在主线程中定义事件,在Task中通过触发事件的形式让主线程捕获到异常,请看代码:
首先定义一个事件参数:
internal class TaskExceptionEventArgs:EventArgs
{
/// <summary>
/// 存放Task引发的异常对象
/// </summary>
public AggregateException AggregateException { get; set; }
}
主代码如下:
class Program
{
private static event EventHandler<TaskExceptionEventArgs> taskExceptionEventHandler;
static void Main(string[] args)
{
//为事件添加事件处理器
taskExceptionEventHandler = (sender, aeArgs) =>
{
Console.WriteLine(aeArgs.AggregateException.Message);
};
Task.Run(async () =>
{
await Task.Delay(2 * 1000);
try
{
throw new AggregateException("内部异常1");
}
catch (AggregateException ex)
{
//触发事件,并传入参数
taskExceptionEventHandler.Invoke(null, new TaskExceptionEventArgs
{
AggregateException = ex
});
}
});
}
}
这样用法很灵活,而且拿到的是最直接的异常对象,并且不用等待Task执行完毕。

Task异常捕获的方式的更多相关文章
- Task异常捕获的几种方式
在调用Task的Wait()方法或Result属性处会抛出Task中的异常. 但是如果没有返回结果,或者不想调用Wait()方法,该怎么获取异常呢? 可以使用ContinueWith()方法 var ...
- .NET Core通过过滤器和中间件两种方式实现全局异常捕获和日志记录
1.一共有五类过滤器IAsyncAuthorizationFilter IAsyncResourceFilter IAsyncActonFilter IAsyncExceptionFilter ...
- C#中try catch中throw ex和throw方式抛出异常有何不同_异常捕获堆栈丢失问题
前言,最近遇到一个使用try-catch异常捕获后记录一下日志,然后再抛出该异常后,异常堆栈里无法显示准确的堆栈地址的问题? 其实以前也遇到过类似问题,没有重视,这次好好研究了下,并上度娘上找了找 ...
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
项目开发中的一些注意事项以及技巧总结 1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...
- WPF异常捕获,并使程序不崩溃!
原文:WPF异常捕获,并使程序不崩溃! 在.NET中,我们使用try-catch-finally来处理异常.但,当一个Exception抛出,抛出Exception的代码又没有被try包围时,程序就崩 ...
- .NET 基础 一步步 一幕幕[数组、集合、异常捕获]
数组.集合.异常捕获 数组: 一次性存储多个相同类型的变量. 一维数组: 语法: 数组类型[] 数组名=new 数组类型[数组长度]; 声明数组的语法: A.数据类型 [] 数组名称= new 数据类 ...
- atitit.js浏览器环境下的全局异常捕获
atitit.js浏览器环境下的全局异常捕获 window.onerror = function(errorMessage, scriptURI, lineNumber) { var s= JSON. ...
- Spring-MVC开发之全局异常捕获全面解读
异常,异常 我们一定要捕获一切该死的异常,宁可错杀一千也不能放过一个! 产品上线后的异常更要命,一定要屏蔽错误内容,以免暴露敏感信息! 在用Spring MVC开发WEB应用时捕获全局异常的方法基本有 ...
- asp.net mvc ,asp.net mvc api 中使用全局过滤器进行异常捕获记录
MVC下的全局异常过滤器注册方式如下:标红为asp.net mvc ,asp.net mvc api 注册全局异常过滤器的不同之处 using SuperManCore; using System. ...
随机推荐
- RTTI之dynamic_cast运算符
#include <iostream> #include <cstdlib> #include <ctime> using std::cout; class Gra ...
- 2.HTML案例二 头条页面
4 HTML案例-头条页面 4.1 案例效果 4.2 案例分析 4.2.1 div布局的进阶 想要将div布局成案例效果,首先需要对多个div进行区分,再分别设置每一个div自身的效果. 1)div的 ...
- .Net Core·寄托于IIS的REST服务405的问题
阅文时长 | 0.48分钟 字数统计 | 828.8字符 主要内容 | 1.引言&背景 2.声明与参考资料 『.Net Core·寄托于IIS的REST服务405的问题』 编写人 | SCsc ...
- centos保存rpm到本地以及使用yum完全卸载软件包
目录 保存安装的rpm到本地 方法一: 方法二(推荐): yum卸载软件包包括依赖 保存安装的rpm到本地 方法一: [root@ServerA ~]# vim /etc/yum.conf [main ...
- KVM性能优化
一.KVM为什么要调优 性能的损耗是关键.KVM采用全虚拟化技术,全虚拟化要由一个软件来模拟硬件,故有一定的损耗,特别是I/O,因此需要优化.KVM性能优化主要在CPU.内存.I/O这几方面.当然对于 ...
- 016.Python闭包函数以及locals和globals
一 闭包函数 内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数 1.1 闭包函数语法 def outer(): a = 5 def inner(): pr ...
- 分布式存储ceph---ceph常用命令(3)
1.查看ceph集群配置信息 ceph daemon /var/run/ceph/ceph-mon.$(hostname -s).asok config show 2.在部署节点修改了ceph.con ...
- shell初学之nginx(域名)
创建两个以域名区分的虚拟网站: 1 #!/bin/bash 2 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/ ...
- STM32 中的HARDFAULT 的查找方法
http://blog.csdn.net/zyboy2000/article/details/7668331
- nginx 的基础知识(一)
Nginx HTTP 和 反向代理web服务器 epoll 占用少的系统资源.支持更多的并发连接 负载均衡 安装简单.配置灵活 热部署.启动快.不间断服务情况下对软件配置进行升级 反向代理 反向代理 ...