Сначала позвольте мне сказать, что я полностью прочитал эту полезную статью и использую класс SafeThread из CodeProject. Я получаю одинаковый результат при использовании Thread или SafeThread.
Я сократил свою проблему до приложения, состоящего из двух форм, каждая с одной кнопкой. Основная программа отображает форму. Когда вы нажимаете эту кнопку, начинается новый поток, который отображает вторую форму. Когда вы нажимаете кнопку во второй форме, она просто «выбрасывает новое исключение ()»
Когда я запускаю это под VS2008, я вижу «Исключение в DoRun ()».
Когда я запускаю за пределами VS2008, я получаю диалоговое окно «Необработанное исключение произошло в вашем приложении. Если вы нажмете продолжить, приложение ....»
Я попытался установить legacyUnhandledExceptionPolicy в app.config как в 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()");
}
}
}
А вот форма2:
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;
}
}