.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 ...
随机推荐
- c#源码如何生成托管代码块
1.使用编程语言编写源码--->编程语言的编译器(面向Clr)---->生成IL代码和元数据(包含:代码中声名的类和成员 以及所引用的成员) 2.IL就被称之为托管代码,因为有Clr管理者 ...
- Gvim 和vim 有什么区别
Gvim 和vim 有什么区别 Gvim是windows的 vim是linux的黑色的命令符 Gvim是单独的窗口下的vim,像notepad一样. vim就是在黑乎乎的cmd窗口下的编辑器.wind ...
- Nginx之OCSP stapling配置
摘要: 正确地配置OCSP stapling, 可以提高HTTPS性能. 什么是OCSP stapling? OCSP的全称是Online Certificate Status Protocol,即在 ...
- 配置安全域名https申请免费证书并配置nginx运行环境
补全信息时选项 在这一步需要去查看进度,下载对应文件上传到对应站点根目录里按照要求建的隐藏类型的文件 如下图 讲证书文件按照下面操作 进行配置项配置https 如下 详情下载附件 server { l ...
- Angular6+ng-zorro实现登录页面
一.效果图 二.html代码 <div class="login-container"> <div class="login-box"> ...
- canvas-7globleCompositeOperation.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 一个JVM进程启动后里面有几个线程
在写Java程序时,通常我们管只有一个main函数(而没有别的Thread或Runnable的程序)叫单线程程序.但是我们写的这个所谓的单线程程序只是JVM这个程序中的一个线程,JVM本身是一个多线程 ...
- GIS开发之数据查询
在GIS开发之我们经常会用到属性查询和空间查询,特别是在数据量比较大的时候,如何提高查询效率成为一个问题 1.属性查询 对于属性查询,除了必要的建索引之外,我们还应该考虑使用字段缓存:减少查询字段,减 ...
- Javascript 对象 - 字符串对象
字符串对象 字符串对象是JavaScript中比较常见的一种基本数据类型,他封装了一个字符串,并且提供了相应的方法.例如连接字符串.取字符串.分割字符串等.JavaScript中字符串是不可变的,原始 ...
- ionic 兼容title居中显示和tab栏在显示底部
在app.js里的 .config 里添加配置,同时在函数中引入 $ionicConfigProvider,具体格式如下所示: .config(function($stateProvider, $ur ...