Pregunta

Leí aquí que debería seguir con hilos STA mientras trabajo dentro de ArcMap. Estaba usando un BackgroudnWorker normal, y mi código se estaba ejecutando muy lentamente. Estoy tratando de cambiarlo para que el trabajador cree un hilo STA dentro y lo haga funcionar en & Quot; heavy & Quot; cosas.

Mi problema ahora es que después de que el segundo hilo termina de funcionar, se liberan todos mis objetos com. Verifiqué si tengo algún tipo de llamada de Mariscal.RelaseComObject o Shutdown, pero no creo que ese sea el caso. ¿Podría ser que solo porque el hilo que recuperó esos objetos com se terminó de ejecutar, los objetos se liberan automáticamente?

aquí está mi ejemplo de código:

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

En la línea # 22, después de la llamada a ProcessSelection, controller.List [0] contiene un objeto com válido. En la línea # 11, después de la llamada thread.Join, el elemento controller.List [0] ya contiene un objeto com liberado. ¿Qué estoy haciendo mal aquí?

¿Fue útil?

Solución

He leído que Single Thread Apartments (STA) solo tienen un solo hilo permitido dentro de ellos (no pensé que fuera tan obvio ...). Entonces, aunque mi hilo principal era STA, y creé otro hilo STA, estaban en compartimentos diferentes.
Cuando mi segundo hilo terminó su trabajo y Dios lo eliminó, el código que llamaba a los objetos COM dentro de ese departamento no podía funcionar (no había hilo para ordenar la llamada. ¿Quizás incluso ya no hay objetos COM?)

De todos modos, todavía no sé cómo usar BackgroundWorker de manera efectiva dentro de ArcMAP. Pero creo que esto explica por qué este intento falló.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top