Jin
Jin

Reputation: 6145

Background worker cannot access object

I have the following set up:

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);

Thread worker function:

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;
}

Finally completed function:

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

However, in the RunWorkerCompleted function, when I try to access e.Result object, it gives me TargetInvocationException and saying that the calling thread does not have access to the object because another thread owns it. Anyone has any insights as to why this is a problem? I simply want to pass the Bar object into RunWorkerCompleted once the background thread finishes.

Thanks.

Upvotes: 1

Views: 611

Answers (1)

brunnerh
brunnerh

Reputation: 184296

Your RunWorkerCompleted event handler should always check the AsyncCompletedEventArgs.Error and AsyncCompletedEventArgs.Cancelled properties before accessing the RunWorkerCompletedEventArgs.Result property. If an exception was raised or if the operation was canceled, accessing the RunWorkerCompletedEventArgs.Result property raises an exception.

The error probably occurred in your background function. See this question for some information on handling cross-thread access of thread-affine objects.

Upvotes: 2

Related Questions