有没有一种方法来定义未处理的异常在一个WinForms .NET 3.5的应用程序的操作?方法来、应用程序、异常、定义

2023-09-03 06:48:09 作者:我也不想丧

请注意,我知道这已经被这里解决。那个帖子讨论异常处理.NET 1.1,而这意味着存在对> .NET 2.0一个更好的解决方案,所以这个问题是特别对最近的.NET版本。

Note, I realize that this has been addressed here. That post discusses exception handling in .NET 1.1 while implying that there is a better solution for >.NET 2.0 so this question is specifically about the more recent .NET versions.

我有一个视窗形式的应用程序,它有望频繁和意外失去到数据库的连接,在这种情况下,它是自身复位到它的初始状态。

I have a windows forms application which is expected to frequently and unexpectedly lose connectivity to the database, in which case it is to reset itself to its initial state.

我已经做了错误日志,重试连接等通过一组装饰在我的自定义DBWrapper对象。之后,采取但是照顾,我想,让通过堆栈错误秋天。一旦它到达顶部,是未处理我想它被吞入,并要执行我的ApplicationResetter.Reset()方法。

I am already doing error logging, retry connection, etc. through a set of decorators on my custom DBWrapper object. After that is taken care of however, I would like to let the error fall through the stack. Once it reaches the top and is unhandled I would like it to be swallowed and my ApplicationResetter.Reset() method to be executed.

谁能告诉我如何做到这一点?

Can anyone tell me how to do this?

如果这是不可能的,那么有没有至少一种方法来处理这​​一点没有介绍关于ApplicationResetter依赖于它可能会收到这样的错误,并没有实际关闭和重新启动我的应用程序(这只是看起来丑陋的)每一类?

If this is impossible, then is there at least a way to handle this without introducing a dependency on ApplicationResetter to every class which might receive such an error and without actually shutting down and restarting my application (which would just look ugly)?

推荐答案

有关Windows窗体的线程(它调用Application.Run()),在主要的开始分配ThreadException处理器()。另外,我发现这是需要调用SetUnhandledExceptionMode:

For Windows Forms threads (which call Application.Run()), assign a ThreadException handler at the beginning of Main(). Also, I found it was necessary to call SetUnhandledExceptionMode:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);
Application.ThreadException += ShowUnhandledException;
Application.Run(...);

下面是一个例子处理程序。我知道这不是你要找的,但它显示了处理程序的格式。请注意,如果你想例外是致命的,你必须显式调用Application.Exit()。

Here is an example handler. I know it's not what you're looking for, but it shows the format of the handler. Notice that if you want the exception to be fatal, you have to explicitly call Application.Exit().

static void ShowUnhandledException(object sender, ThreadExceptionEventArgs t)
{
	Exception ex = t.Exception;
	try {
		// Build a message to show to the user
		bool first = true;
		string msg = string.Empty;
		for (int i = 0; i < 3 && ex != null; i++) {
			msg += string.Format("{0} {1}:\n\n{2}\n\n{3}", 
				first ? "Unhandled " : "Inner exception ",
				ex.GetType().Name,
				ex.Message, 
				i < 2 ? ex.StackTrace : "");
			ex = ex.InnerException;
			first = false;
		}
		msg += "\n\nAttempt to continue? (click No to exit now)";

		// Show the message
		if (MessageBox.Show(msg, "Unhandled exception", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No)
			Application.Exit();
	} catch (Exception e2) {
		try {
			MessageBox.Show(e2.Message, "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
		} finally {
			Application.Exit();
		}
	}
}