2

が付いたWPFウィンドウがあり BackgroundWorkerます。Send()ここのメソッドで例外が発生します:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
     smtpClient.Send(mail);
}

Clickこれは、次のようなボタンのイベントで呼び出されます。

private async void SendClickAsync(object sender, RoutedEventArgs e)
{
    using (MessageServiceClient client = new MessageServiceClient())
    {
        try
        {
            [...]
            worker.RunWorkerAsync();

        }
        catch (Exception ex)
        {
            MessageBox.Show("Error! Check your sender data!", "!", MessageBoxButton.OK, MessageBoxImage.Error);
            [...]
        }
    }
}

この例外が処理されないのはなぜですか?私が非同期ではなく(すべてがSendClickAsync()メソッド内にあった)それを行っていたとき、メッセージボックスはうまくポップアップしました。

4

3 に答える 3

12

メソッドを呼び出すworker.RunWorkerAsync()と、メインスレッドは実行を継続し、try..catchブロックを終了します。例外を処理するには、RunWorkerCompletedイベントハンドラを使用します。RunWorkerCompletedEventArgs引数には、例外オブジェクトを含むプロパティErrorがあります。

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
       MessageBox.Show("Error", "!", MessageBoxButton.OK, MessageBoxImage.Error);
       return;
    }
}
于 2012-12-08T21:48:50.953 に答える
3

BackgroundWorkerスレッドプールスレッドを使用しているため、コードがワーカースレッドで奇妙なことを実行できるようにする必要はありません。そのため、のBackgroundWorker間に発生した例外を飲み込み、DoWorkそれがを介して発生したことを通知しますRunWorkerCompletedEventArgs.Error

于 2012-12-08T21:50:58.780 に答える
2

例外が処理されない理由は、別のスレッドでスローされるためです。toの呼び出しworker.RunWorkerAsync();はブロックせず、スレッドプールでジョブを開始し、メインスレッドですぐに制御を返します。これが非同期で実行するための要点です。

ただし、これは、メインスレッドの呼び出しがworker.RunWorkerAsync()try-catchブロックを終了した後、例外が(メインスレッドで)処理されないことも意味します。

于 2012-12-08T21:54:34.707 に答える