3

BackgroundWorker _DoWorkで長いプロセスを実行する関数を呼び出すBackgroundWorkerがあります。関数でエラーが発生すると、カスタマイズされたメッセージボックスが表示されます。

 WPFMessageBoxResult result = WPFMessageBox.Show("Activation Fail", "Error!!", WPFMessageBoxButtons.OK, WPFMessageBoxImage.Error);

以下の例外は、WPFMessageBoxResultクラスで発生します。

The calling thread must be STA, because many UI components require this. 

ありがとうございました。

4

4 に答える 4

4

バックグラウンドスレッドからUIコンポーネントを操作しようとしないでください。

1つの方法は、doWorkメソッドで例外をキャッチし、それをbackgroundworkerのresultプロパティに割り当ててから、その結果が例外のタイプであるかどうか、または結果を他の目的で使用していない場合はnullでないかどうかを確認することです。次に、backgroundWorker_completedイベントでそれを確認します。

BackgroundWorker_DoWork(sender, )
{
    try
    {
       // do work        
    }
    catch (Exception ex)
    {
         BackgroundWorker w = sender as BackgroundWorker;
         if (w != null)
             w.Result = ex;
    }
}

それから

BackgroundWorker_Completed()
{
    if (s.Result != null && e.Result is Exception)
    {
       Exception ex = e.Result as Exception;
       // do something with ex
    }
}
于 2012-10-04T03:51:33.567 に答える
4

通常、Winforms / WPFでは、長時間実行されるタスクからUIを操作する必要がある場合は、Invoke()を使用してUIスレッドにジャンプします。UIに属する任意のオブジェクトからinvokeを呼び出すことができますが、invokeスコープ内では、実行するコードをできるだけ少なくするようにしてください。このコードはUIスレッド上にあるため、時間がかかりすぎるとUIがブロック/ハングします。

public void BackgroundWorkerMethod()
{
    try
    {
        // do work
    }
    catch (Exception e)
    {
        uiObject.Invoke(new Action(() => {
            // now you are on the UI thread
            Message.ShowMessage(e.Message);
        });
    }
}
于 2012-10-04T04:24:18.127 に答える
3

バックグラウンドスレッドは単なるワーカースレッドであり、ユーザーインターフェイススレッドではありません。WPFとWinFormsはどちらも、ユーザーインターフェイスコードがスレッドセーフではないため、ユーザーインターフェイスアクションを実行するスレッドをSTA(シングルスレッドアパートメント)としてマークする必要があります。また、Windowsメッセージがディスパッチされるように、メッセージポンプを追加する必要があります。

ワーカースレッドにメッセージボックスを表示する代わりに、メインのユーザーインターフェイススレッドにメッセージを送信し、そのスレッドにメッセージボックスを表示させることをお勧めします。これを行うには、メインUIスレッドからワーカースレッドにディスパッチャーへの参照を渡す必要があります。次に、Dispatcher.BeginInvokeを使用して、メインスレッドでデリゲートをコールバックするように要求します。

または、バックグラウンドスレッドが完了するのを待ってから、結果を確認し、ユーザーに適切な回答を表示することもできます。いずれにせよ、ワーカースレッドはユーザーインターフェイスと直接対話してはなりません。

于 2012-10-04T03:51:10.087 に答える
3

この方法を使用する必要があります

 void BGW_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                 Button btn = new Button();
                 btn.Width = 100;
                 btn.Height = 50;
                 btn.Content = "Test";
                 myG.Children.Add(btn);
            }
            ));
        }
            catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }
于 2015-02-15T19:28:05.603 に答える