TargetInvocationException от BackgroundWorker_RunWorkerCompleted

Предположим, следующая ситуация. Форма имеет кнопку, которая при щелчке запускает фоновый рабочий. В обработчике событий RunWorkerCompleted есть фрагмент кода, который генерирует необработанное исключение. Форма запускается из метода Application.Run.

public partial class FormMain : Form
{
    public FormMain()
    {
        InitializeComponent();
    }

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        throw new Exception();
    }

    private void button_Click(object sender, EventArgs e)
    {
        backgroundWorker.RunWorkerAsync();
    }
}

Проблема заключается в том, что Visual Studio разрывается при вызове Application.Run вместо "throw new Exception()" в методе FormMain.backgroundWorker_RunWorkerCompleted. Вдобавок к этому реальному исключению помещается TargetInvocationException, а стек вызовов сокращается до метода Program.Main и кода, вызвавшего исключение, из-за этого невозможно проверить.

Как предотвратить эту упаковку? Я делаю что-то по сути неправильно?

Судя по стеку вызовов, поставляемому с TargetInvocationException, существует много сложенных методов вызова, слишком много для моего базового понимания циклов обработки сообщений и не очень базового понимания потоков.

РЕДАКТИРОВАТЬ: я знаю, что есть свойство InnerException в TargetInvocationException и что ошибка может быть отслежена, посмотрев туда, но это не вопрос. Вопрос в том, как заставить Visal Studio остановиться перед переносом реального исключения в TargetInvocationException, чтобы я мог использовать все эти приятные функции отладки, которые предоставляет VS IDE.

1 ответ

Решение

Да, это неприятный побочный эффект от магии, которая запускает событие RunWorkerCompleted в потоке пользовательского интерфейса. Нет написанного вами кода, который бы заставил его работать, поэтому отладчик не может показать ничего релевантного, кроме последнего оператора в вашей программе, который все еще был задействован, вызова Application.Run(), который запустил цикл обработки сообщений.

Вы должны отладить это, заставляя отладчик останавливаться при возникновении исключения. Отладка + Исключения, отметьте флажок Брошенный для исключений CLR. Также обратите внимание на поведение, когда вы запускаете это без отладчика, вы получите диалог Wheel Of Fortune. Исправьте это с помощью Application.SetUnhandledExceptionMode().

Другие вопросы по тегам