首先,让我说一下我已经彻底阅读了this useful article并使用CodeProject中的SafeThread类。使用Thread或SafeThread时,我得到的结果是一样的。
我将我的问题缩小到一个包含两个表单(每个表单都有一个按钮)的应用程序。主程序显示一个表单。当你点击该按钮时,会启动一个新的线程,显示第二个表单。当你在第二个表单上点击按钮时,它内部只是执行 "throw new Exception()"。
当我在VS2008下运行这个应用程序时,我看到 "Exception in DoRun()"。
当我在VS2008之外运行时,我会看到一个对话框,显示 "Unhandled exception has occurred in your application. If you click continue, the application ...."
我尝试在app.config中将legacyUnhandledExceptionPolicy设置为1和0。
当不在VS2008下运行时,我需要做什么来捕获在我的第二个表单中抛出的异常?
这是我的Program.cs
static class Program
{
[STAThread]
static void Main()
{
Application.ThreadException += new ThreadExceptionEventHandler (Application_ThreadException);
Application.SetUnhandledExceptionMode (UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new Form1());
}
catch(Exception ex)
{
MessageBox.Show("Main exception");
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("CurrentDomain_UnhandledException");
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show("Application_ThreadException");
}
}
这是表单1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SafeThread t = new SafeThread(new SimpleDelegate(ThreadMain));
try
{
t.ShouldReportThreadAbort = true;
t.ThreadException += new ThreadThrewExceptionHandler(t_ThreadException);
t.ThreadCompleted += new ThreadCompletedHandler(t_ThreadCompleted);
t.Start();
}
catch(Exception ex)
{
MessageBox.Show(string.Format("Caught externally! {0}", ex.Message));
}
}
void t_ThreadCompleted(SafeThread thrd, bool hadException, Exception ex)
{
MessageBox.Show("t_ThreadCompleted");
}
void t_ThreadException(SafeThread thrd, Exception ex)
{
MessageBox.Show(string.Format("Caught in safe thread! {0}", ex.Message));
}
void ThreadMain()
{
try
{
DoRun();
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Caught! {0}", ex.Message));
}
}
private void DoRun()
{
try
{
Form2 f = new Form2();
f.Show();
while (!f.IsClosed)
{
Thread.Sleep(1);
Application.DoEvents();
}
}
catch(Exception ex)
{
MessageBox.Show("Exception in DoRun()");
}
}
}
这里是 Form2:
public partial class Form2 : Form
{
public bool IsClosed { get; private set; }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
throw new Exception("INTERNAL EXCEPTION");
}
protected override void OnClosed(EventArgs e)
{
IsClosed = true;
}
}