問題タブ [apartments]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - シングル スレッド アパートメント モデル - ワーカー スレッドを作成する COM オブジェクトを処理する方法は?
STA EXE に実装された COM オブジェクトがあります ( を呼び出します)。これを実装CoInitialize(NULL)
するものと呼びましょう。擬似コードは次のようになります。CMyObject
IControl
私のテスト コードは基本的にこのパターンに従い、(今のところ) 問題なく動作しますが、STA で MSDN を読むと、次のようにする必要があることが示唆されます。
- コール
CoInitialize
/CoUninitialze
インThreadMain
- マーシャリングを使用してワーカー スレッドからインターフェイスを呼び出す
この質問 ( How to access COM objects from different apartment models? ) も、マーシャリングが必要であることを示唆しており、GIT の使用を提唱しています。
ただし、アパートメント モデルは COM の一部であり、実際に理解したことはありません。これが自分の状況で必要であることを確認したかったのです。特に、現在エラーが発生することなく正常に動作しているため、コードを追加したくありません」それが必要な場合に備えて、私にはわかりません」.
違いがある場合、問題の COMISomething
オブジェクトは、メイン スレッドではなく、ワーカー スレッドによってのみ呼び出されます。私の特定のケースでは、CMyObject
常に1つだけが存在します。
c# - 「AppDomain.ExecuteAssembly」でロードされたコードの COM アパートメント状態を設定するにはどうすればよいですか?
を作成するときThread
、開始する前にその COM アパートメントの状態を明示的に設定するオプションがあります。例えば:
しかし、 を作成AppDomain
してそれにコードをロードすると、スレッドの作成を明示的に制御できないように見えるため、 を呼び出す方法がありませんSetApartmentState
。
内部で作成されたメイン/エントリ スレッドがAppDomain
特定の COM アパートメント状態を使用するように指定する方法はありますか?
のメイン エントリ メソッドをor属性Plugin.dll
でマークできることはわかっています。がCOM アパートメントの状態を明示的に宣言または設定しておらず、変更できないと仮定しましょう。[STAThread]
[MTAThread]
Plugin.dll
Plugin.dll
c++ - マーシャリングするかマーシャリングしないか
次の質問に対する明確な答えを見つけることができませんでした: COM クラスがスレッド セーフである場合、つまり、Both または Free でマークされている場合、そのオブジェクト インターフェイスをマーシャリングして、同じプロセス内の別のスレッドに渡す必要がありますか? 両方のスレッドが MTA に属している場合については質問しません。各スレッドが独自の STA に属している場合について質問します。
異なるアパートメントに属するスレッド間のインターフェイスをマーシャリングするルールについて知っています。私の質問は、生のインターフェイス ポインターを別のアパートメントのスレッドに渡し、各スレッドがスレッド セーフなオブジェクトのメソッドを呼び出すとどうなるかということです。
私の経験によると、それは問題なく動作します。私の質問は、それが時間の問題であり、危険であり、何らかの理由でクラッシュにつながる可能性があるか、それとも完全に安全であり、ルールがあるのが良いかということです?
multithreading - FreeThreadedDOMDocument、ニュートラル アパートメント、フリースレッド マーシャラー
MSDN が述べているように:
シングル スレッド アプリケーション (または一度に 1 つのスレッドだけが DOM にアクセスするマルチスレッド アプリケーション) を作成している場合は、レンタル スレッド モデル (Msxml2.DOMDocument.3.0 または Msxml2.DOMDocument.6.0) を使用します。複数のスレッド アクセスが同時に DOM にアクセスするアプリケーションを作成している場合は、フリー スレッド モデル (Msxml2.FreeThreadedDOMDocument.3.0 または Msxml2.FreeThreadedDOMDocument.6.0) を使用します。
FreeThreadedDOMDocument、ニュートラル アパートメント、およびフリースレッド マーシャラーの間に何らかの関連はありますか? OleView を調べたところ、FreeThreadedDOMDocument スレッド モデルが Both であることがわかりました。私の知る限り、ニュートラル アパートメント オブジェクトはフリースレッド マーシャラーでサポートされています。FreeThreadedDOMDocument はフリー スレッド マーシャラーを使用しておらず、フリー スレッドとして少し紛らわしいと呼ばれているということですか?
Free、Both、または Neutral としてマークされた COM クラス間の実装の違いは何ですか? 私が理解している限り、それらはすべてスレッドセーフでなければなりませんが、なぜ違いがあるのでしょうか? ニュートラルがフリースレッドのマーシャラーをサポートするというのは正しいですか?
c# - C# でスレッド アパートメントを横断するときのエラー「型の COM オブジェクトをキャストできません」
Windows 10 で .NET 4.5.2 を使用して、C# 内から参照された dll としてサード パーティの SDK を使用してきました。IDE は dll に関する相互運用機能を作成し、適切な名前空間、インターフェイス、列挙型などを確認できます私が使用している SDK は Blackmagic ATEM Television Studio 用ですが、直接関係はないと思います。
SDK は、接続されたハードウェアを検索/検出するために使用できるオブジェクトを提供し、オブジェクトのインスタンスを返します。これは、基になる COM オブジェクトのラッパー (RCW) のように見えます。
検出コードは次のようになります。
STA アパートメントである WPF UI スレッドでこのコードを実行すると、問題なく動作します。オブジェクトをエラーなく使用できます。ただし、新しいスレッド (STA または MTA) から結果のスイッチャー オブジェクトにアクセスしようとすると、次のようなエラーが表示されます。
タイプ「System.__ComObject」の COM オブジェクトをインターフェイス タイプ「BMDSwitcherAPI.IBMDSwitcherMixEffectBlock」にキャストできません。IID '{11974D55-45E0-49D8-AE06-EEF4D5F81DF6}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーのために失敗したため、この操作は失敗しました: サポートされているそのようなインターフェイスはありません (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) .
MikeJ と同様の質問に対する彼の回答から引用します。
この厄介な例外は、COM マーシャリングと呼ばれる概念のために発生します。問題の本質は、任意のスレッドから COM オブジェクトを使用するために、スレッドが COM オブジェクトを記述する型情報にアクセスできる必要があるという事実にあります。
この時点で、戦略を少し変更して、MTA スレッド内から検出ロジックを呼び出してみることにしました。このような:
これは機能するようですが、コストがかかります。
トレードオフは、バックグラウンド (MTA) スレッドからスイッチャーオブジェクトを問題なく操作できるようになったことですが、約 15 分間実行すると、アプリケーション全体が単純にクラッシュします。誰かがそれを言う前に、私はこれがスレッドセーフでないことを知っています。複数の MTA スレッドがスイッチャーオブジェクトを使用しようとする前に、何らかの同期ロジックが必要であることを認識しています。現時点では、上記のコードを実行してアプリケーションを 15 分間アイドル状態にすると、毎回クラッシュします。
そのため、一方では安定したアプリを使用していますが、UI スレッドからしかライブラリを使用できず、他方では不安定なアプリを使用していますが、任意の (MTA) バックグラウンド スレッドからライブラリを使用できます。
私のアプリの性質上、複数のバックグラウンド スレッドからライブラリを使用できることが望ましいでしょう。たとえば、1 つのスレッドがグラフィックスを生成してデバイスにアップロードし、別のスレッドがビデオ入力の切り替えを管理し、3 つ目のスレッドがオーディオ入力を管理し、UI スレッドが ID-10T ボンク ダイアログを処理しているとします。 UI スレッドから実行することもできますが、できれば避けたいと思います。
それで、UI(STA)スレッドでスイッチャーオブジェクトを発見して作成する方法はありますか(理論的には15分で爆発するのを避けます)、タイプ情報をバックグラウンド(MTA)スレッドにアクセスできるようにして、バックグラウンド(MTA)スレッドも使用できるようにしますスイッチャー?_ または、バックグラウンド (MTA) スレッドでスイッチャーオブジェクトを検出/作成しても安全ですが、その 15 分間の爆発を避けるために特別な方法でそれを「マーク」する必要がありますか?
編集:
Hans Passant のコメントを読み、彼が提供したリンクを調査した後、参照されている STAThread クラスを WPF で使用するために適合させました。しかし、私は SynchronizationContext と Dispatcher について少し曖昧です。以下にリストされている私のコードは、「長時間実行」操作中に UI をブロックすることなく、COM オブジェクトの「周り」のラッパーとして安全に使用できますか? 私の使用例は、いくつかのデータを準備する Task() を実行してから、いくつかのコードを呼び出して COM オブジェクトと対話し、操作が完了すると、実行中のタスクでコード フローが再開され、次の一連の操作を実行することです。 .
powershell - 実行可能なscriptblockとApartmentState引数を使用してPowerShellでスレッドを設定するにはどうすればよいですか?
スレッドを設定して、実行可能コードで開始するにはどうすればよいApartmentState = "STA"
ですか? このメソッドを見つけただけですが、スクリプトブロックを渡す方法がわかりません。
次のように、このスレッドでクリップボードのテキストを取得する必要があります。
私も試しStart-Job
ました。