C#自定义异常处理(自定义例外)
来源:互联网 发布:老mac升级系统 编辑:程序博客网 时间:2024/05/16 10:38
http://www.cnblogs.com/winnerlan/archive/2008/05/24/1206644.html
对.NET类来说,一般的异常类 System.Exception派生于 System.Object。还有许多定义好的异常类(如:System.SystemException、System.ApplicationException等),他们又派生于 System.Exception 类。其中System.ApplicationException类是第三方定义的异常类,如果我们要自定义异常类,那么就应派生于它。
我们要站在异常一定可能会发生的角度来编写异常处理程序,应对程序有可能发生的错误建立一个良好的异常处理策略。在做异常处理的时候,最好能在应用程序所有的入口处(事件处理函数,主函数,线程入口)使用try-catch。但是不要在程序构造函数入口处添加try-catch,因为此处产生异常,它自己并没有能力来处理,因为它还没有构造完毕,只能再向外层抛出异常。
但我们也不能盲目使用异常。而且使用异常,可能会在一定程度上影响到程序的性能(C#中使用异常一般不影响性能)。
// 自定义异常类
public class MyException : ApplicationException
{
public MyException(string message) : base(message)
{
}
public MyException(string message,Exception innerException)
: base(message,innerException)
{
}
}
public class MyException : ApplicationException
{
public MyException(string message) : base(message)
{
}
public MyException(string message,Exception innerException)
: base(message,innerException)
{
}
}
全局异常处理、多线程中的异常处理
将全局异常处理函数的委托加入到 Application.ThreadException中,实现全局异常处理,但它只能处理主线程中未捕获的异常。在多线程异常处理时,工作线程/辅线程中产生异常,可以把它转给主线程来完成异常处理。如果线程之间不通知,是无法直接捕捉异常的。若没有去处理工作线程/辅线程中产生的异常,该异常将会“消失”掉。
为什么要把异常处理都交给主线程去做呢?举个例子:在WinForm里我们使用多线程来处理界面元素,一旦有异常发生就将异常消息显示出来。那么,是直接在异常发生后就MessageBox,还是将消息交给MainUI来统一显示?试想一下,程序要是复杂点或是有多个界面采用多线程来显示界面元素,那么采用前者,我们就算知道了异常的详细信息,但可能还是很难找到究竟是哪里出了问题。而通过MainUI来显示,情况就要好很多了,尤其是还设计到其他东西的时候(如:多语言环境)。当然,这个例子只是很小的一个方面。下面就来看怎么来实现:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace ThreadApp
{
public class frmMain : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btRun;
///
/// 必需的设计器变量。
///
private System.ComponentModel.Container components = null;
public delegate void WorkerThreadExceptionHandlerDelegate(Exception e);
void WorkerThreadExceptionHandler(Exception e)
{
this.Text = "Disposed.";
MainUIThreadExceptionHandler(this, new System.Threading.ThreadExceptionEventArgs(e));
}
public frmMain()
{
InitializeComponent();
}
///
/// 清理所有正在使用的资源。
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
Windows 窗体设计器生成的代码
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
Application.ThreadException += new ThreadExceptionEventHandler(MainUIThreadExceptionHandler);
Application.Run(new frmMain());
}
public static void MainUIThreadExceptionHandler(Exception e)
{
MainUIThreadExceptionHandler(null, new System.Threading.ThreadExceptionEventArgs(e));
}
public static void MainUIThreadExceptionHandler(object sender, ThreadExceptionEventArgs t)
{
MessageBox.Show(t.Exception.Message,"Exception",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
private void ThrowException()
{
throw new NotImplementedException();
}
private void Run()
{
try
{
this.Text = "Waiting"; //[错误]这里在2.0里是编译不通过的。因为它已经违背了我们的原则——不要跨线程操作(当前线程对界面线程的元素进行了操所)
Thread.Sleep(2000);
this.Text = "Throw Exception";
ThrowException();
this.Text = "Finished"; //[错误](同上)
}
catch(Exception e)
{
// 如果涉及到多线程的互操作时,
// 可以运用BeginInvoke方法来实现多线程间的互访问。
this.BeginInvoke(
new WorkerThreadExceptionHandlerDelegate(
WorkerThreadExceptionHandler),
new object[]{e}); }
}
private void btRun_Click(object sender, System.EventArgs e)
{
ThreadStart ts = new ThreadStart(Run);
Thread t = new Thread(ts);
t.Start();
//throw new NotSupportedException();
}
}
}
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace ThreadApp
{
public class frmMain : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btRun;
///
/// 必需的设计器变量。
///
private System.ComponentModel.Container components = null;
public delegate void WorkerThreadExceptionHandlerDelegate(Exception e);
void WorkerThreadExceptionHandler(Exception e)
{
this.Text = "Disposed.";
MainUIThreadExceptionHandler(this, new System.Threading.ThreadExceptionEventArgs(e));
}
public frmMain()
{
InitializeComponent();
}
///
/// 清理所有正在使用的资源。
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
Windows 窗体设计器生成的代码
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
Application.ThreadException += new ThreadExceptionEventHandler(MainUIThreadExceptionHandler);
Application.Run(new frmMain());
}
public static void MainUIThreadExceptionHandler(Exception e)
{
MainUIThreadExceptionHandler(null, new System.Threading.ThreadExceptionEventArgs(e));
}
public static void MainUIThreadExceptionHandler(object sender, ThreadExceptionEventArgs t)
{
MessageBox.Show(t.Exception.Message,"Exception",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
private void ThrowException()
{
throw new NotImplementedException();
}
private void Run()
{
try
{
this.Text = "Waiting"; //[错误]这里在2.0里是编译不通过的。因为它已经违背了我们的原则——不要跨线程操作(当前线程对界面线程的元素进行了操所)
Thread.Sleep(2000);
this.Text = "Throw Exception";
ThrowException();
this.Text = "Finished"; //[错误](同上)
}
catch(Exception e)
{
// 如果涉及到多线程的互操作时,
// 可以运用BeginInvoke方法来实现多线程间的互访问。
this.BeginInvoke(
new WorkerThreadExceptionHandlerDelegate(
WorkerThreadExceptionHandler),
new object[]{e}); }
}
private void btRun_Click(object sender, System.EventArgs e)
{
ThreadStart ts = new ThreadStart(Run);
Thread t = new Thread(ts);
t.Start();
//throw new NotSupportedException();
}
}
}
- C#自定义异常处理(自定义例外)
- PL/SQL_处理例外2(非预定义异常、自定义异常)
- C#自定义异常处理
- C#自定义异常处理
- Oracle 10g处理例外(即sql异常)学习二——自定义例外和非预定义例外
- 自定义例外
- java异常(例外)处理
- C#自定义异常处理类2【转载】
- C#自定义异常处理类1【转载】
- 自定义异常处理(样例)
- C++基础知识(八)例外、异常处理
- oracle 自定义例外
- PL/SQl自定义例外
- 异常处理+异常+处理异常+自定义异常
- 关于系统例外和自定义例外
- VB自定义异常处理
- 自定义异常处理
- 自定义异常处理
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
- tomcat 6.0配置oracle数据库连接池
- Makefile中的wildcard函数(用来获取指定目录下的文件)
- 代理模式
- php标记
- C#自定义异常处理(自定义例外)
- 杭电1285
- hnoi2013
- div仿框架布局之典型的两栏布局
- 大话设计模式 状态模式
- LNMP一键安装包的Nginx 502 Bad Gateway错误可能原因及解决方法
- C#中htmlencode与InnerHtml的区别
- java学习计划
- How many