0

我在这里读到我应该在 ArcMap 中工作时坚持使用 STA 线程。我使用的是普通BackgroudnWorker的,我的代码运行得很慢。我正在尝试更改它,以便工作人员在内部创建一个 STA 线程并让它在“重”的东西上运行。

我现在的问题是,在第二个线程完成工作后,我所有的 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 对象。我在这里做错了什么?

4

1 回答 1

0

我读过单线程公寓(STA)里面只允许有一个线程(我不认为这很明显......)。因此,即使我的主线程是 STA,并且我创建了另一个 STA 线程,它们也位于不同的隔间。
当我的第二个线程完成他的工作并且上帝处置时,该公寓内调用 COM 对象的代码无法执行(没有线程可以编组调用。甚至可能不再有 COM 对象了?)

无论如何,我仍然不知道如何在 ArcMAP 中有效地使用 BackgroundWorker。但我认为这解释了为什么这次尝试失败了。

于 2009-07-01T06:10:18.560 回答