10

私は次のコンポーネントを使用しています。

  • ライブラリ(例外をスローします)
  • ロギングをテストするためのテストコンソール
  • エンタープライズライブラリの例外処理アプリケーションブロック
  • エンタープライズライブラリロギングアプリケーションブロック

私はbackgroundworkerを使用してlibraryメソッドを呼び出しています。ライブラリは例外をスローしますが、RunWorkerCompletedハンドラーが呼び出されることはありません。

例外をキャッチする唯一の方法は、DoWorkハンドラーコードをtry/catchブロックで囲むことです。

RunWorkerCompletedEventArgs.Errorプロパティを誤解しましたか?BackgroundWorkerによってキャッチされた例外を取得するためではありませんか?

コードサンプル:

static BackgroundWorker w = new BackgroundWorker();

w.DoWork += new DoWorkEventHandler(w_DoWork);
w.RunWorkerCompleted += 
   new RunWorkerCompletedEventHandler(w_RunWorkerCompleted);
w.RunWorkerAsync();



static void w_DoWork(object sender, DoWorkEventArgs e)
{
   MyClass m  = new MyClass();
   w.result = m.Compute();
}

static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   if (e.Error != null)
   {
      HandleException(e.Error);
   }

   /* result related code */

}


static void HandleException(Exception e)
{
   ExceptionPolicy.HandleException(e, "MyPolicy");
}

上記のサンプルは、コンソールアプリケーションの終了につながります。vs2010の出力は、まったく何も書き込みません(デフォルトの出力のみ)。

では、どこに問題があるのでしょうか。

//編集:このスニペットは、ライブラリの例外をキャッチするために機能します。

static void w_DoWork(object sender, DoWorkEventArgs e)
{
   try
   {
      MyClass m  = new MyClass();
      w.result = m.Compute();
   }catch(Exception e){ }

}
4

1 に答える 1

7

これがBackgroundWorkerの正しいパターンです。

問題はMain、BWが完了する前にメソッドが終了していることだと思います。

RunWorkerAsyncすぐに戻ります。待機していない場合はMain、おそらくBWが開始する前であっても、プロセスは終了します。完了してもかまいません。

Console.ReadLineメソッドの最後にを追加してみてくださいMain


興味がない:

BWは、コンソールアプリとWindowsアプリで動作が異なります。WinFormsまたはWPFアプリを使用する場合、UIスレッドに派生したSynchronizationContextがあり、BWはUIスレッドにマーシャリングRunWorkerCompletedして、そこで実行します。これがBWの主なメリットの1つです。

コンソールアプリでは、デフォルトのSynchronizationContextが使用され、これRunWorkerCompletedがスレッドプールスレッドにマーシャリングされます。これは、Mainスレッドをブロックしても、完了したハンドラーが引き続き実行されることを意味します。

于 2012-04-24T14:17:12.500 に答える