ArcMap и BackgroundWorkerThread - PullRequest
       19

ArcMap и BackgroundWorkerThread

0 голосов
/ 10 мая 2009

Я читал здесь, я должен придерживаться потоков STA при работе внутри ArcMap. Я использовал обычный BackgroudnWorker, и мой код работал очень медленно. Я пытаюсь изменить это так, чтобы рабочий создал поток STA внутри и заставил его работать на «тяжелом» материале.

Моя проблема сейчас в том, что после того, как 2-й поток завершил работу, все мои com-объекты были освобождены. Я проверил, есть ли у меня какой-то вызов marshal.RelaseComObject или Shutdown, но я не думаю, что это так. Может ли быть так, что я просто потому, что поток, который извлекал эти com-объекты, выполняется, объекты автоматически освобождаются?

вот мой пример кода:

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

В строке # 22, после вызова ProcessSelection, controller.List [0] содержит допустимый com-объект. В строке # 11 после вызова thread.Join элемент controller.List [0] уже содержит освобожденный объект com. Что я здесь не так делаю?

1 Ответ

0 голосов
/ 01 июля 2009

Я читал, что в однопоточных квартирах (STA) внутри них разрешен только один поток (я не думал, что это было так очевидно ...). Поэтому, хотя моим основным потоком был STA, и я создал другой поток STA, они были в разных отделениях.
Когда мой 2-й поток закончил свою работу, и бог распорядился, код, вызывающий COM-объекты внутри этой квартиры, не мог работать (не было потока, чтобы маршалировать вызов. Может быть, даже больше не COM-объекты?)

В любом случае, я до сих пор не знаю, как эффективно использовать BackgroundWorker внутри ArcMAP. Но я думаю, это объясняет, почему эта попытка не удалась.

...