Widzę pewne dziwne zachowanie podczas rzucania wyjątków i łapania ich w obsłudze zdarzeń Application.ThreadException
.Dlaczego wyjątek wewnętrzny osiąga obsługę wątku ThreadException, a nie rzeczywisty zgłoszony wyjątek?
Zasadniczo, co dzieje się w poniższym przykładzie, wyjątek jest zgłaszany do obsługi zdarzeń DoWork
z BackgroundWorker
. Obsługa zdarzeń RunWorkerCompleted
ponownie rzuca nowy wyjątek z oryginałem jako wewnętrznym wyjątkiem.
Dlaczego wewnętrzny wyjątek pojawia się w procedurze obsługi zdarzeń ThreadException
, a nie wyjątek acutal jest zgłaszany? Jeśli nie udostępnię wewnętrznego wyjątku w module obsługi zdarzeń RunWorkerCompleted
, pojawi się poprawny wyjątek.
using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace WierdExceptionApp
{
class WierdExceptionForm : Form
{
BackgroundWorker worker = new BackgroundWorker();
public WierdExceptionForm()
{
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
throw new Exception("worker_RunWorkerCompleted", e.Error);
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
throw new Exception("worker_DoWork");
}
[STAThread]
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new WierdExceptionForm());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
}
}
Zdumiewające; to mnie gryzie przez lata, nie zdając sobie z tego sprawy. Widziałbym te okazjonalne raporty o błędach dotyczące rzeczy, które mogłem przeklinać. Rzadko zdarzało się, że nie spędzali zbyt wiele czasu na ich zaglądanie, ale w końcu zaczęło się to dziać z czymś znaczącym i zdałem sobie sprawę, że wyjątek zmienia się po drodze. WTF ?? –