2009-05-10 3 views
0

Je lis ici Je devrais m'en tenir aux threads STA tout en travaillant à l'intérieur d'ArcMap. J'utilisais un BackgroudnWorker normal, et mon code fonctionnait très lentement. J'essaye de le changer de sorte que le travailleur crée un fil de STA à l'intérieur et l'obtienne pour fonctionner sur les choses «lourdes».ArcMap et BackgroundWorkerThread

Mon problème maintenant est qu'après que le 2ème thread a fini de fonctionner, tous mes objets com sont libérés. J'ai vérifié si j'avais une sorte d'appel marshal.RelaseComObject ou Shutdown, mais je ne pense pas que ce soit le cas. Se pourrait-il que je juste parce que le fil qui a récupéré ces objets de com est exécuté, les objets sont automatiquement libérés?

ici est mon exemple de code:

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

ligne n ° 22, après l'appel ProcessSelection, controller.List [0] contient un objet COM valide. Sur la ligne 11, après l'appel thread.Join, l'élément controller.List [0] contient déjà un objet com publié. Qu'est-ce que je fais de mal ici?

Répondre

0

J'ai lu que Single Thread Apartments (STA) n'a qu'un seul thread autorisé à l'intérieur d'eux (je ne pensais pas que c'était évident ...). Donc, même si mon fil principal était STA, et j'ai créé un autre thread STA, ils étaient sur des compartiments différents.
Quand mon 2ème fils a terminé son travail et Dieu disposé, le code appelant objets COM à l'intérieur cet appartement ne pouvait pas effectuer (il n'y avait pas de fil à marshall l'appel. Peut-être même pas d'objets COM plus?)

Quoi qu'il en soit, je reste Je ne sais pas comment utiliser BackgroundWorker efficacement dans ArcMAP. Mais je pense que cela explique pourquoi cette tentative a échoué.

Questions connexes