views:

122

answers:

1

I read in here I should stick with STA threads while working inside ArcMap. I was using a normal BackgroudnWorker, and my code was running really slowly. I am trying to change it so that the worker creates an STA thread inside and gets it to run on the "heavy" stuff.

My problem now is that after the 2nd thread is done working, all my com objects are released. I checked if I have some kind of marshal.RelaseComObject or Shutdown call, but I don't think that is the case. Could it be that I just because the thread that retrieved those com objects is done running, the objects are being automatically released?

here is my code sample:

 private void bckgrndWrkrController_DoWork(object sender, DoWorkEventArgs e)
 {
  BackgroundWorker worker = sender as BackgroundWorker;
  if (worker != null)
  {
   controller.BackgroundWorker = worker;
   Thread thread = new Thread(STAProcessSelection);
   thread.SetApartmentState(ApartmentState.STA);
   thread.Start(e.Argument);
   thread.Join();
   e.Result = processingResult;
   e.Cancel = worker.CancellationPending;
  }
 }

 private void STAProcessSelection(object argument)
 {
  ISelection selection = argument as ISelection;
  if (selection != null)
  {
   processingResult = controller.ProcessSelection(selection);
  }
 }

 private void bckgrndWrkrController_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
  if (e.Error != null)
  {
   MessageBox.Show(e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  }
  else if (e.Result is bool)
  {
   // Making sure the thread was not cancelled after we got the result
   processingResult = (bool)e.Result && !worker.CancellationPending;
   if (processingResult)
   {
    // Set the datasource of the grid
    bindingSource.DataSource = controller.List;
   }
  }

  // and inform the command we are done
  OnDoneProcessing(EventArgs.Empty);
 }

On line #22, after the ProcessSelection call, controller.List[0] contains a valid com object. On line #11, after the thread.Join call, the controller.List[0] element already contains a released com object. What am I doing wrong in here?

A: 

I've read that Single Thread Apartments (STA) only have a single thread allowed inside of them (I didn't think it was that obvious...). So even though my main thread was STA, and I created another STA thread, they were on different compartments.
When my 2nd thread finished his job and god disposed, code calling COM objects inside that apartment could not perform (there was no thread to marshall the call to. Maybe even no COM objects anymore?)

Anyway, I still don't know how to effectively use BackgroundWorker inside ArcMAP. But I think this explains why this attempt failed.

Noam Gal