网上找到两个方式,一个简单的只是做个记录,另一个能像QQ一样提交到后台。

方法一:

static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
try
{
//设置应用程序处理异常方式:ThreadException处理
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//处理UI线程异常
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//处理非UI线程异常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); #region 应用程序的主入口点
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
#endregion
}
catch (Exception ex)
{
string str = GetExceptionMsg(ex,string.Empty);
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string str = GetExceptionMsg(e.Exception, e.ToString());
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
//LogManager.WriteLog(str);
} static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string str = GetExceptionMsg(e.ExceptionObject as Exception, e.ToString());
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
//LogManager.WriteLog(str);
} /// <summary>
/// 生成自定义异常消息
/// </summary>
/// <param name="ex">异常对象</param>
/// <param name="backStr">备用异常消息:当ex为null时有效</param>
/// <returns>异常字符串文本</returns>
static string GetExceptionMsg(Exception ex,string backStr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("****************************异常文本****************************");
sb.AppendLine("【出现时间】:" + DateTime.Now.ToString());
if (ex != null)
{
sb.AppendLine("【异常类型】:" + ex.GetType().Name);
sb.AppendLine("【异常信息】:" + ex.Message);
sb.AppendLine("【堆栈调用】:" + ex.StackTrace);
}
else
{
sb.AppendLine("【未处理异常】:" + backStr);
}
sb.AppendLine("***************************************************************");
return sb.ToString();
}
}

方法二:

转载于:王旭博客 » C# 全局异常处理。

1.本文目标

我们准备做一个程序,具备全局的异常捕获及处理能力,类似大多数知名程序那样弹个窗口,发送错误报告,友好的提示。类似腾讯QQ异常,Firefox异常等异常窗口来进行错误报送,如下图所示:

2.C#异常处理机制简介

C#也跟其他的OOP语言一样能够处理可预见的异常信息,如网络连接失败,文件读取失败,数组越界等异常。当你的程序遇到了异常的时候CLR会抛出一个异常给你,这样你就得到了一个处理异常的机会,这个异常会一层一层的返回给调用者,最后返回到Main方法的起始点中,但是如果你没有进行处理的话最终会被CLR处理,它将终止程序。

3. C#全局异常捕获处理

目前为止,很多的程序都是以感觉哪段代码可能异常就把它try起来然后弹个Message的方式进行提示,好一点处理的还会记录日志信息来解决。如果纯粹看简单的错误提示其实是很难找到错误的,尤其是程序越来越大的时候,甚至有时候你都不知道这个错误是哪个模块出现的,是怎么出现的,点击哪个按钮出现的!是不是得去问客户?在我看来极大多数情况是完全没有必要的,我们完全有能力捕获完整的异常。
好了,废话解释完毕,开始构建我们的具备异常处理捕获及处理能力的程序吧!这里以Winform举例,其他的都差不多,如WPF什么的都是可以捕获全局异常的

3.1 构建Bug处理模块

首先我建了个Winform项目命名为 WinformException 用于处理Bug,为了利于以后项目复用 这个项目是单独用于处理Bug的,在该项目中构建了如下窗体。

这个用于对Bug报送的处理,对客户的错误解释界面,你可以根据自己的业务需求进行更改,总而言之把错误完整的保存下来即可。

出现错误不可怕,可怕的是出了错 你却不知道。

窗口的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms; namespace WinformException
{
public partial class FrmBugReport : Form
{
#region 全局变量
Exception _bugInfo;
#endregion #region 构造函数
/// <summary>
/// Bug发送窗口
/// </summary>
/// <param name="bugInfo">Bug信息</param>
public FrmBugReport(Exception bugInfo)
{
InitializeComponent();
_bugInfo = bugInfo;
this.txtBugInfo.Text = bugInfo.Message;
lblErrorCode.Text = Guid.NewGuid().ToString();
} /// <summary>
/// Bug发送窗口
/// </summary>
/// <param name="bugInfo">Bug信息</param>
/// <param name="errorCode">错误号</param>
public FrmBugReport(Exception bugInfo, string errorCode)
{
InitializeComponent();
_bugInfo = bugInfo;
this.txtBugInfo.Text = bugInfo.Message;
lblErrorCode.Text = errorCode;
}
#endregion #region 公开静态方法
/// <summary>
/// 提示Bug
/// </summary>
/// <param name="bugInfo">Bug信息</param>
/// <param name="errorCode">错误号</param>
public static void ShowBug(Exception bugInfo, string errorCode)
{
new FrmBugReport(bugInfo, errorCode).ShowDialog();
} /// <summary>
/// 提示Bug
/// </summary>
/// <param name="bugInfo">Bug信息</param>
public static void ShowBug(Exception bugInfo)
{
ShowBug(bugInfo, Guid.NewGuid().ToString());
}
#endregion private void btnDetailsInfo_Click(object sender, EventArgs e)
{
MessageBox.Show("异常详细信息:" + _bugInfo.Message + "\r\n跟踪:" + _bugInfo.StackTrace);
} }
}

这个项目就完成了。

3.2 构建异常测试程序

接下来构建我们的测试程序,以及如何捕捉代码。我在解决方案中再建了一个Winform项目命名为WinformTest做测试,如下图所示:

 先来看看我们在 Program.cs 中做了什么手脚吧,这个就是全局捕捉异常的核心代码,Program.cs 代码如下:

using System;
using System.Collections.Generic;
using System.Windows.Forms; namespace WinformTest
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//全局异常捕捉
Application.ThreadException += Application_ThreadException; //UI线程异常
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; //多线程异常 Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
} //UI线程异常
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
WinformException.FrmBugReport.ShowBug(e.Exception);
} //多线程异常
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
WinformException.FrmBugReport.ShowBug((Exception)e.ExceptionObject);
}
}
}

第一行我注册了UI线程异常处理事件

  1. Application.ThreadException += Application_ThreadException; //UI线程异常

这个用于捕获主线程的错误,也就是UI,大多数异常都会聚集在此,我们在该事件中处理了异常,程序则不会强制退出。

然后第二行注册了其他多线程异常处理事件(除UI之外的线程)

  1. AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; //多线程异常

这个用于捕获主线程之外的所有线程的异常,但是无法让程序不被强制退出,当在这里面的代码执行完毕后程序依然会退出!不过幸运的是我们有其他的办法来解决

然后看看测试窗体 FrmMain.cs 的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms; namespace WinformTest
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
} //普通异常测试
private void btnTest1_Click(object sender, EventArgs e)
{
throw new Exception("啊..我这行代码异常了...");
} //多线程异常测试
private void btnTest2_Click(object sender, EventArgs e)
{
Thread th = new Thread(() => { throw new Exception("啊哦,异常错误。"); });
th.IsBackground = true;
th.Start();
}
}
}

其实就是两个简单的测试而已,点击按钮会弹出如下界面。

我们可以在确定按钮中编写发送到数据库,或者是把bug详细信息存放到txt中。拿到了Exception,由你任意处置吧,我这里把ExceptionStackTrace属性展示到了错误详细信息按钮上,不会看StackTrace的,该反省下了。耐心看下就明白了,是很简单的,它对Bug是如何出现的步骤表示的非常清楚。

好了到此为止,Bug处理也就OK了,还算非常简单的,只是可能我长篇大论了。哈..下次尽量简短..现在应该掌握了对异常的合理处理了吧。

该解决方案的源码下载:WinformException

小知识:如何处理多线程中的异常,让程序不会强制退出。
你可以这样,把多线程中的任务全部try起来。

 Thread t = new Thread((ThreadStart)delegate
{
try
{
throw new Exception("多线程异常");
}
catch (Exception error)
{
MessageBox.Show("线程异常:" + error.Message + Environment.NewLine + error.StackTrace);
}
});
t.Start();

你还可以这样,把异常抛回主线程,这个比较推荐。

 Thread t = new Thread((ThreadStart)delegate
{
try
{
throw new Exception("非窗体线程异常");
}
catch (Exception ex)
{
this.BeginInvoke((Action)delegate
{
throw ex;
});
}
});
t.Start();

【第一篇笔记】C# 全局容错,全局异常的更多相关文章

  1. 轻松学C#----第一篇笔记

    C#是微软公司推出的一种面向对象的开发语言,于2002年发布,经历了10年的发展,已经广泛应用于各种生产领域.以它为基础语言的ASP.NET已经称为主流网站开发技术.[入门] 共三章: 第一篇:C#概 ...

  2. C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路

    C#不用union,而是有更好的方式实现   用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...

  3. WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对

    WPF MVVM UI分离之<交互与数据分离>   在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...

  4. ASP.NET Core 学习笔记 第一篇 ASP.NET Core初探

    前言 因为工作原因博客断断续续更新,其实在很早以前就有想法做一套关于ASP.NET CORE整体学习度路线,整体来说国内的环境的.NET生态环境还是相对比较严峻的,但是干一行爱一行,还是希望更多人加入 ...

  5. 《javascript权威指南》读书笔记——第一篇

    <javascript权威指南>读书笔记——第一篇 金刚 javascript js javascript权威指南 由于最近想系统学习下javascript,所以开始在kindle上看这本 ...

  6. .net开发笔记(十三) Winform常用开发模式第一篇

    上一篇博客最后我提到“异步编程模型”(APM),之后本来打算整理一下这方面的材料然后总结一下写篇文章与诸位分享,后来在整理的过程中不断的延伸不断地扩展,发现完全偏离了“异步编程”这个概念,前前后后所有 ...

  7. asp.net捕获全局未处理异常的几种方法

    通过HttpModule来捕获未处理的异常[推荐] 首先需要定义一个HttpModule,并监听未处理异常,代码如下: public void Init(HttpApplication context ...

  8. asp.net 捕获全局未处理异常的几种方法

    通过HttpModule来捕获未处理的异常[推荐] 首先需要定义一个HttpModule,并监听未处理异常,代码如下: public void Init(HttpApplication context ...

  9. unix环境高级编程-读书笔记与习题解答-第一篇

    从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...

随机推荐

  1. scikit-learn 机器学习库

    一 介绍 scikit-learn是Python的一个开源机器学习模块,它建立在NumPy,SciPy和matplotlib模块之上.值得一提的是,scikit-learn最先是由David Cour ...

  2. Java从入门到放弃——05.修饰符static,final,权限修饰符

    本文目标 static final: 权限修饰符:public,private,protected,缺省 1.static 静态修饰符,被static修饰的变量或者方法会被加载进静态区内存,不需要创建 ...

  3. 利用Angular2的Observables实现交互控制

    在Angular1.x中,我们使用Promise来处理各种异步.但是在angular2中,使用的是Reactive Extensions (Rx)的Observable.对于Promise和Obser ...

  4. 【转】c# 读取excel数据的两种方法

    源地址:http://www.cnblogs.com/icyJ/p/ReadExcel.html

  5. Linux之杀掉进程

    pkill命令可以按照进程名杀死进程.pkill和killall应用方法差不多,也是直接杀死运行中的程序:如果您想杀掉单个进程,请用kill来杀掉. 语法 pkill(选项)(参数) 选项 -o:仅向 ...

  6. Flink学习笔记-支持的数据类型

    说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...

  7. P3272 [SCOI2011]地板

    \(\color{#0066ff}{ 题目描述 }\) lxhgww的小名叫"小L",这是因为他总是很喜欢L型的东西.小L家的客厅是一个R*C的矩形,现在他想用L型的地板来铺满整个 ...

  8. SPI 实现原理及运用

    SPI原理 SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的.在java.util.ServiceLoader的文档里有比较详 ...

  9. poj1964最大子矩阵 (单调栈加枚举)

    题目传送门 题目大意: 一个矩阵中,求F组成的矩阵的面积,(答案乘以三). 思路:n如果是小于100的,就可以通过前缀和,然后三重循环暴力找,和poj1050很像,但由于是1000,就不可以了,时间复 ...

  10. APPcrawler基础原理解析及使用

    一.背景 一年前,我们一直在用monkey进行Android 的稳定性测试 ,主要目的就是为了测试app 是否会产生Crash,是否会有ANR,页面错误等问题,在monkey测试过程中,实现了脱离Ca ...