Я использую событие Application.ThreadException для обработки и регистрации неожиданных исключений в моем приложении winforms.Очень странное поведение Application.ThreadException
Теперь, где-то в моем приложении, у меня есть следующий код (или, скорее, что-то эквивалент, но этот фиктивный код достаточно, чтобы воспроизвести мой вопрос):
try
{
throw new NullReferenceException("test");
}
catch (Exception ex)
{
throw new Exception("test2", ex);
}
Я явно ожидал моего Application_ThreadException обработчика, которому нужно передать исключение «test2», но это не всегда так. Как правило, , если другой поток упорядочивает мой код в пользовательском интерфейсе, мой обработчик получает «тестовое» исключение, точно так же, как если бы я не поймал «тест» вообще.
Ниже приведен пример, воспроизводящий такое поведение. Я пропустил код дизайнера.
static class Program
{
[STAThread]
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // has no impact in this scenario, can be commented.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//this handler is never called
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Console.WriteLine(e.Exception.Message);
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Click+=new EventHandler(button1_Click);
}
protected override void OnLoad(EventArgs e) {
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThrowEx));
t.Start();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
throw new NullReferenceException("test");
}
catch (Exception ex)
{
throw new Exception("test2", ex);
}
}
void ThrowEx()
{
this.BeginInvoke(new EventHandler(button1_Click));
}
}
Вывод этой программы на моем компьютере:
test
... here I click button1
test2
Я воспроизвел на .net 2.0,3.5 и 4.0. У кого-то есть логическое объяснение?
Изменен ответ. –
Ваше предложение имеет смысл, но это не меняет странного поведения. – Brann
@Brann, вы правы.Странное поведение сохраняется. Тем не менее, я исправил это, не делая 'catch (Exception ex)' в обработчике щелчка, а просто 'catch'. Очень интересно. Исключено исключение decendand Exception. –