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

在访问RunWorkerCompletedEventArgs.Result属性之前,您的RunWorkerCompleted事件处理程序应始终检查AsyncCompletedEventArgs.ErrorAsyncCompletedEventArgs.Cancelled属性。如果引发异常或取消操作,则访问RunWorkerCompletedEventArgs.Result属性会引发异常。

该错误可能发生在您的后台功能中。有关处理线程仿射对象的跨线程访问的一些信息,请参阅此问题。

于 2012-08-21T20:07:13.477 回答