1

私は次の設定をしています:

BackgroundWorker backgroundInstancesWorker = new BackgroundWorker();
backgroundInstancesWorker.DoWork += new DoWorkEventHandler(EnumerateInstances);
backgroundInstancesWorker.WorkerReportsProgress = false;
backgroundInstancesWorker.WorkerSupportsCancellation = false;
backgroundInstancesWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundInstancesWorker_RunWorkerCompleted);

// Create temporary tuple to hold the argument information
// X is type IEnumerable<Foo>, Y is type Bar
object arguments = new object[2] { X, Y };
backgroundInstancesWorker.RunWorkerAsync(arguments);

スレッド ワーカー関数:

private static void EnumerateInstances(object sender, DoWorkEventArgs e)
{
     object[] arguments = e.Argument as object[];
     var queryCounterSets = arguments[0] as IEnumerable<Foo>;
     var sourceItem = arguments[1] as Bar;
     e.Result = sourceItem;
}

最後に完成した機能:

private static void backgroundInstancesWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
      if (e.Result != null && e.Result is Bar)
      {
          // Do stuff
      }
}

ただし、RunWorkerCompleted 関数では、e.Result オブジェクトにアクセスしようとすると、TargetInvocationException が返され、別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドがオブジェクトにアクセスできないと表示されます。なぜこれが問題なのか、誰にも洞察がありますか? バックグラウンド スレッドが終了したら、単に Bar オブジェクトを RunWorkerCompleted に渡したいだけです。

ありがとう。

4

1 に答える 1

2

RunWorkerCompletedイベント ハンドラーは、RunWorkerCompletedEventArgs.Result プロパティにアクセスする前に、AsyncCompletedEventArgs.Error および AsyncCompletedEventArgs.Cancelled プロパティを常にチェックする必要あります。例外が発生した場合、または操作がキャンセルされた場合、RunWorkerCompletedEventArgs.Resultプロパティにアクセスすると例外が発生します。

バックグラウンド関数でエラーが発生した可能性があります。スレッド アフィン オブジェクトのクロススレッド アクセスの処理に関する情報については、この質問を参照してください。

于 2012-08-21T20:07:13.477 に答える