web-dev-qa-db-ja.com

STAThreadおよびマルチスレッド

STAThreadに関するMSDNの記事から:

アプリケーションのCOMスレッドモデルがシングルスレッドアパートメント(STA)であることを示します。

(参考までに、それは 記事全体 です。)

シングルスレッドアパートメント... OKまた、アプリケーションがCOM相互運用機能を使用しない限り、この属性は実際には何もしません。それで、それは正確に何をし、マルチスレッドアプリケーションにどのように影響しますか?マルチスレッドアプリケーション(スレッドプールなどだけでなく、Timersを使用するすべてのユーザーから非同期メソッド呼び出しまでを含む)は、MTAThreadを使用する必要がありますか? STAThreadとMTAThreadは実際に何をしますか?

102

アパートメントスレッドはCOMの概念です。 COMを使用しておらず、呼び出すAPIがいずれも「隠れて」COMを使用していない場合は、アパートメントについて心配する必要はありません。

アパートを意識する必要がある場合、詳細は やや複雑 になります。おそらく簡略化されたバージョンは、STAとしてタグ付けされたCOMオブジェクトをSTAThreadで実行する必要があり、MTAとマークされたCOMオブジェクトをMTAスレッドで実行する必要があるということです。これらのルールを使用して、COMはこれらの異なるオブジェクト間の呼び出しを最適化し、必要のない場所でのマーシャリングを回避できます。

59
Bruce

それにより、COINIT_APARTMENTTHREADEDをパラメーターとして指定してCoInitializeが呼び出されます。 COMコンポーネントまたはActiveXコントロールを使用しない場合、まったく影響はありません。その場合、それは重要なことです。

アパートメントスレッドであるコントロールは、事実上シングルスレッドであり、それらに対して行われた呼び出しは、作成されたアパートメントでのみ処理できます。

MSDNの詳細:

シングルスレッドアパートメント(STA)で作成されたオブジェクトは、アパートメントのスレッドからのみメソッド呼び出しを受け取るため、呼び出しはシリアル化され、メッセージキューの境界にのみ到着します(Win32関数PeekMessageまたはSendMessageが呼び出された場合)。

マルチスレッドアパートメント(MTA)のCOMスレッドで作成されたオブジェクトは、いつでも他のスレッドからメソッド呼び出しを受信できる必要があります。通常、クリティカルセクション、セマフォ、ミューテックスなどのWin32同期プリミティブを使用して、オブジェクトのデータを保護するために、マルチスレッドオブジェクトのコードに何らかの形式の同時実行制御を実装します。

ニュートラルスレッドアパートメント(NTA)で実行するように構成されたオブジェクトが、STAまたはMTAにあるスレッドによって呼び出されると、そのスレッドはNTAに転送されます。このスレッドがその後CoInitializeExを呼び出すと、呼び出しは失敗し、RPC_E_CHANGED_MODEを返します。

3