.Net下的全局异常捕获问题
全局异常捕获主要目标并不是为了将异常处理掉防止程序崩溃。因为当错误被你的全局异常捕获器抓到的时候,已经证实了你程序中存在BUG。
一般而言,我们的全局异常捕获主要作用就是接收到异常之后进行异常的反馈。
大家都知道,异常是通过Throw命令抛出,一路从抛出的模块里上抛,如果中途没有被try...catch...抓住的话就会一直抛到CLR(公共语言运行时)。如果用栈来描述这个过程的话,那就是异常会从栈的栈顶一路下沉,直到中途被try...catch...抓住或者直至沉到栈底,被CLR接住。CLR接收到异常之后的处理方式非常的简单粗暴——直接报错,然后关闭程序。
只要我们在程序把异常抛给CLR之前,抢先把异常捕获,那就可以做到全局异常处理了。不过这个try...catch...就必须放在栈的最下方。程序运行时栈的最下方函数其实就是程序运行时第一个调用的函数——main()函数。
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
}
catch (Exception ex)
{
MessageBox.Show(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
}
}
下面我们运用其他来处理全局异常。
一、Application.ThreadException
假设还是之前的那个程序,我们将程序的Program.cs内容填入以下代码: static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException += Application_ThreadException; Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
} static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Exception ex = e.Exception;
MessageBox.Show(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace));
}
}
二、子线程异常捕获AppDomain.CurrentDomain.UnhandledException
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
} static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
MessageBox.Show(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}\r\nCLR即将退出:{3}", ex.GetType(), ex.Message, ex.StackTrace, e.IsTerminating));
}
三、WPF的异常捕获
public App()
{
this.Startup += new StartupEventHandler(App_Startup); this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);//UI线程的异常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);//非UI线程的异常
System.Threading.Tasks.TaskScheduler.UnobservedTaskException += App_UnobservedTaskException;//异步线程的异常 } void App_Startup(object sender, StartupEventArgs e)
{
bool ret;
mutex = new System.Threading.Mutex(true, "WpfMuerterrrterterttex", out ret);
if (!ret)
{
MessageBox.Show("课堂已经启动!");
Environment.Exit();
}
} void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (e.ExceptionObject is System.Exception)
{ }
} void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
} void App_UnobservedTaskException(object obj, System.Threading.Tasks.UnobservedTaskExceptionEventArgs e)
{ } int MyExceptionfilter(ref long a)
{
MessageBox.Show(a.ToString());
return ;
} 在此处理未处理的异常:
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//注册Application_Error
this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
}
//异常处理逻辑
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
//处理完后,我们需要将Handler=true表示已此异常已处理过
MessageBox.Show("程序执行时遇到未处理异常,即将关闭!\n错误信息:"+e.Exception.Message);
Environment.Exit(0);
e.Handled = true;
}
}
四、公共语言未能捕获的异常
引入API
public delegate int CallBack(ref long a);
CallBack mycall; [System.Runtime.InteropServices.DllImport("kernel32")]
private static extern Int32 SetUnhandledExceptionFilter(CallBack cb); [System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int GetWindowText(IntPtr hWnd, ref string strBuffer, int nSize);
WPF的App中
mycall = new CallBack(MyExceptionfilter);
SetUnhandledExceptionFilter(mycall);
处理:
int MyExceptionfilter(ref long a)
{
MessageBox.Show(a.ToString());
return ;
}
.Net下的全局异常捕获问题的更多相关文章
- atitit.js浏览器环境下的全局异常捕获
atitit.js浏览器环境下的全局异常捕获 window.onerror = function(errorMessage, scriptURI, lineNumber) { var s= JSON. ...
- 使用spring利用HandlerExceptionResolver实现全局异常捕获
最近一直没有时间更新是因为一直在更新自己使用的框架. 之后会慢慢带来对之前使用的spring+mvc+mybatis的优化. 会使用一些新的特性,实现一些新的功能. 我会尽量分离业务,封装好再拿出来. ...
- springboot(二 如何访问静态资源和使用模板引擎,以及 全局异常捕获)
在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /static / ...
- Configure、中间件与ErrorHandlingMiddleware全局异常捕获
一.Configure Startup.cs中的Configure方法主要是http处理管道配置.中间件和一些系统配置,其中 IApplicationBuilder: 定义一个类,该类提供配置应用程序 ...
- Android全局异常捕获
PS:本文摘抄自<Android高级进阶>,仅供学习使用 Java API提供了一个全局异常捕获处理器,Android引用在Java层捕获Crash依赖的就是Thread.Uncaught ...
- .NET Core整合log4net以及全局异常捕获实现
在使用log4net之前先安装log4net.这里操作很简单,通过nuget下载并安装log4net很方便.如下图. log4net配置 <?xml version="1.0" ...
- springboot 全局异常捕获,异常流处理业务逻辑
前言 上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的.参数异常springboot默认的返回结构: { "timestamp": ...
- 【快学springboot】5.全局异常捕获,异常流处理业务逻辑
前言 上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的.参数异常springboot默认的返回结构: { "timestamp": ...
- SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...
随机推荐
- SpringBoot中并发定时任务的实现、动态定时任务的实现(看这一篇就够了)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10659045.html,否则将追究法律责任!!! 一.在JAVA开发领域,目前可以通过以下 ...
- HashMap深度解析
最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样.当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片 ...
- 8.异常_EJ
第57条: 只针对异常情况才使用异常 异常是为了在异常情况下使用而设计的,不要将它们用于普通的控制流,也不要编写迫使它们这么做的API. 第58条: 对可恢复的情况使用受检异常,对编程错误使用运行时异 ...
- angular分页插件tm.pagination 解决触发二次请求的问题
angular分页插件tm.pagination(解决触发二次请求的问题) DEMO: http://jqvue.com/demo/tm.pagination/index.html#?current ...
- Java NIO 学习
Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...
- 一个简单的scrollTop动画的方法
var autoScrollTop = function (param) { var delay = param.scrollDom.height() * 20; param.dom.animate( ...
- TFS 2017 持续集成速记
VS2017许多激动人 心的功能,升级! TFS2017也升级,不支持SQL2012,升级!不过貌似开发版不能升级,好吧,开发版升2014企业版! 2017据说不支持XAML生成了,但后台菜单中还 ...
- Python函数式编程(二):常见高级函数
一个函数的参数中有函数作为参数,这个函数就为高级函数. 下面学习几个常见高级函数. ---------------------------------------------------------- ...
- 你不可不知的Java引用类型之——PhantomReference源码详解
定义 PhantomReference是虚引用,该引用不会影响不会影响对象的生命周期,也无法从虚引用中获取对象实例. 说明 源码介绍部分其实也没多大内容,主要内容都在前面介绍中说完了.PhantomR ...
- Git忽略规则及.gitignore规则不生效的解决办法(转)
在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件).这个文件每一行保存了一个匹配的规则例如: 1 2 3 ...