2009-05-10 5 views
0

Ich lese hier, ich sollte mit STA-Threads bei der Arbeit in ArcMap bleiben. Ich benutzte eine normale BackgroudnWorker, und mein Code lief sehr langsam. Ich versuche, es zu ändern, so dass der Arbeiter einen STA-Thread innerhalb erstellt und es auf dem "schweren" Zeug ausführen lässt.ArcMap und BackgroundWorkerThread

Mein Problem ist jetzt, dass, nachdem der 2. Thread fertig ist, alle meine com-Objekte freigegeben sind. Ich habe überprüft, ob ich eine Art Marshal.RelaseComObject oder Shutdown Call habe, aber ich denke nicht, dass das der Fall ist. Könnte es sein, dass ich, nur weil der Thread, der diese com-Objekte abgerufen hat, ausgeführt wird, werden die Objekte automatisch freigegeben?

hier ist mein Codebeispiel:

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, nach dem ProcessSelection Anruf, controller.List [0] ein gültiges COM-Objekt enthält. In Zeile 11 enthält das Element controller.List [0] nach dem Aufruf thread.Join bereits ein freigegebenes com-Objekt. Was mache ich hier falsch?

Antwort

0

Ich habe gelesen, dass Single Thread Apartments (STA) nur einen einzigen Thread innerhalb von ihnen erlaubt haben (ich dachte nicht, dass es so offensichtlich war ...). Obwohl mein Hauptthema STA war und ich einen anderen STA-Thread erstellt habe, befanden sie sich in verschiedenen Abteilungen.
Als mein zweiter Thread seinen Job und Gott angeordnet abgeschlossen, Code COM-Objekte innerhalb dieser Wohnung Aufruf nicht durchführen konnte (es gab keinen Thread zu marshall den Anruf an. Vielleicht sogar ohne COM-Objekte mehr?)

Wie dem auch sei, ich habe noch Ich weiß nicht, wie man BackgroundWorker in ArcMAP effektiv einsetzt. Aber ich denke, das erklärt, warum dieser Versuch gescheitert ist.