Pergunta

Eu li aqui eu deveria ficar com threads STA enquanto trabalhava dentro ArcMap. Eu estava usando um BackgroudnWorker normal, e meu código estava funcionando muito lentamente. Eu estou tentando mudar isso para que o trabalhador cria um interior thread STA e recebe-lo para ser executado no material "pesado".

O meu problema agora é que após o 2º segmento é feito de trabalho, todos os meus objetos COM são liberados. Eu verifiquei se eu tiver algum tipo de marshal.RelaseComObject ou chamada de Shutdown, mas eu não acho que é o caso. Poderia ser que eu só porque o segmento que recuperou aqueles com objetos é feita em execução, os objetos estão sendo liberados automaticamente?

aqui é o meu exemplo 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);
    }

Na linha # 22, após a chamada ProcessSelection, controller.List [0] contém um objeto com válida. Na linha # 11, após a chamada Thread.Join, o controller.List [0] elemento já contém um objeto com liberado. O que estou fazendo de errado aqui?

Foi útil?

Solução

Eu li que único segmento Apartments (STA) só tem um único segmento permitidos dentro deles (eu não acho que foi tão óbvio ...). Assim, mesmo que o meu thread principal foi STA, e eu criei outro segmento STA, eles estavam em diferentes compartimentos.
Quando meu segundo segmento terminado seu trabalho e Deus dispostos, código de chamada COM objetos dentro desse apartamento não poderia realizar (não havia nenhuma linha para marshall a chamada. Talvez até não COM objetos mais?)

De qualquer forma, eu ainda não sei como usar eficazmente BackgroundWorker dentro ArcMAP. Mas eu acho que isso explica por que essa tentativa falhou.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top