0

ここで読んだのは、ArcMap内で作業している間はSTAスレッドに固執する必要があるということです。私は通常のを使用していましたが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オブジェクトが既に含まれています。私はここで何が間違っているのですか?

4

1 に答える 1

0

シングルスレッドアパート(STA)には、内部で許可されているスレッドが1つしかないことを読みました(それほど明白だとは思いませんでした...)。したがって、メインスレッドがSTAであり、別のSTAスレッドを作成したとしても、それらは異なるコンパートメントにありました。
私の2番目のスレッドが仕事を終えて神が処分されたとき、そのアパート内のCOMオブジェクトを呼び出すコードは実行できませんでした(呼び出しをマーシャリングするスレッドがありませんでした。おそらくCOMオブジェクトさえもうありませんか?)

とにかく、ArcMAP内でBackgroundWorkerを効果的に使用する方法はまだわかりません。しかし、これがこの試みが失敗した理由を説明していると思います。

于 2009-07-01T06:10:18.560 に答える