12

COM と STA/MTA に関する多くの質問がありますが (例:ここ)、そのほとんどは UI を備えたアプリケーションに関するものです。ただし、次の設定があります。

  • デフォルトでマルチスレッド アパートメントであるコンソール アプリケーション (Main() には明示的に[MTAThread]属性があります)。
  • メイン スレッドは、いくつかのワーカー スレッドを生成します。
  • メイン スレッドは、シングル スレッドの COM オブジェクトをインスタンス化します。
  • メイン スレッドは、ユーザーが「q」を押すまで Console.ReadLine() を呼び出します。その後、アプリケーションは終了します。

いくつかの質問:

  • COM オブジェクトのメッセージ ポンプの必要性について言及している箇所は数多くあります。この質問が示唆するように、メイン スレッドのメッセージ ポンプを手動で作成する必要がありますか、それとも CLR が新しい STA スレッドでメッセージ ポンプを作成しますか?
  • 念のために言っておきますが、CLR が必要な配管を自動的に作成すると仮定すると、明示的な同期を必要とせずに任意のワーカー スレッドから COM オブジェクトを使用できますか?
  • 性能面で優れているのは次のうちどれですか。
    • COM オブジェクトとの間のマーシャリングは CLR に任せます。
    • 別の STA スレッドでオブジェクトを明示的にインスタンス化し、他のスレッドにConcurrentQueue.
4

3 に答える 3

5

メインスレッド用のメッセージポンプを手動で作成する必要がありますか?

いいえ。MTA 内にあるため、メッセージ ポンプは必要ありません。

または、CLR は新しい STA スレッドでそれを作成しますか?

COM がスレッドを作成すると (プロセスに STA がないため)、メッセージ ポンプも作成されます (および隠しウィンドウ: SPY++ および同様のデバッグ ツールで表示できます)。

明示的な同期を必要としない任意のワーカー スレッドからの COM オブジェクト

依存します。

シングル スレッド オブジェクト (STO) への参照が MTA で作成された場合、COM は適切なプロキシを提供します。このプロキシは、MTA 内のすべてのスレッドに適しています。

それ以外の場合は、参照をマーシャリングして、正しいプロキシを持つようにする必要があります。

パフォーマンスの面で優れています

これに対する唯一の答えは、両方をテストして比較することです。

(STA のスレッドを作成し、ローカルでオブジェクトをインスタンス化する場合は、メッセージ ポンピングを行う必要があることを思い出してください。CLR レベルの軽量メッセージ ポンプがあるかどうかはわかりません。 )

注意。COM と CLR について詳しく説明しているのは、Adam Nathan による.NET と COM: The Complete Interoperability Guide (Sams、2002 年 1 月) だけです。ただし、これは .NET 1.1 に基づいており、現在は絶版になっています (ただし、Kindle 版があり、Safari Books Onlineから入手できます)。この本でさえ、あなたがやろうとしていることを直接説明していません。プロトタイプを作成することをお勧めします。

于 2014-01-30T10:23:44.163 に答える
5

はい、MTAスレッドからSTA COM オブジェクトを作成することは可能です。

この場合、COM ( CLRではない) は、暗黙的な STA アパートメント (別の COM 所有のスレッド) を作成するか、以前に作成された既存のアパートメントを再利用します。そこで COM オブジェクトがインスタンス化され、それに対してスレッドセーフなプロキシ オブジェクト (COM マーシャリング ラッパー) が作成され、MTA スレッドに返されます。MTA スレッドで行われたオブジェクトへのすべての呼び出しは、COM によってその暗黙的な STA アパートメントにマーシャリングされます。

通常、このシナリオは望ましくありません。これには多くの欠点があり、COM がオブジェクトの一部のインターフェイスをマーシャリングできない場合、期待どおりに機能しない可能性があります。詳細については、この質問を確認してください。さらに、暗黙的な STA アパートメントによって実行されるメッセージ ポンプ ループは、限られた数の COM 固有のメッセージのみをポンプします。これは、COM の機能にも影響を与える可能性があります。

あなたはそれを試すことができ、それはあなたにとってうまくいくかもしれません. または、診断が非常に難しい、デッドロックなどの不快な問題に遭遇することもあります。

これは、私が最近回答した密接に関連する質問です。

StaTaskScheduler および STA スレッド メッセージのポンピング

ThreadAffinityTaskScheduler個人的には、私の回答で提案されているようなものを使用して、スレッド間呼び出しとスレッド アフィニティのロジックを手動で制御することを好みます。

こちらもお読みください: INFO: Descriptions and Workings of OLE Threading Models、強くお勧めします。

于 2014-01-30T10:21:30.497 に答える