次の方法で共有


Windows でのマネージド スレッドとアンマネージド スレッド処理

すべてのスレッドの管理は、共通言語ランタイムによって作成されたスレッドや、コードを実行するためにマネージド環境に入るランタイムの外部で作成されたスレッドなど、 Thread クラスを介して行われます。 ランタイムは、マネージド実行環境内でコードを実行したプロセス内のすべてのスレッドを監視します。 他のスレッドは追跡されません。 スレッドは、COM 相互運用機能を使用してマネージド実行環境に入ることができます (ランタイムはマネージド オブジェクトを COM オブジェクトとしてアンマネージ ワールドに公開するため)、COM DllGetClassObject 関数、プラットフォーム呼び出しを行います。

COM 呼び出し可能ラッパーなどのアンマネージ スレッドがランタイムに入ると、システムはそのスレッドのスレッド ローカル ストアをチェックして、内部マネージド Thread オブジェクトを検索します。 見つかった場合、ランタイムはこのスレッドを既に認識しています。 ただし、見つからない場合、ランタイムは新しい Thread オブジェクトをビルドし、そのスレッドのスレッド ローカル ストアにインストールします。

マネージド スレッドでは、 Thread.GetHashCode は安定したマネージド スレッド識別です。 スレッドの有効期間中、この値を取得するアプリケーション ドメインに関係なく、他のスレッドの値と競合することはありません。

Win32 スレッドからマネージド スレッドへのマッピング

次の表は、Win32 スレッド要素を同等のおおよそのランタイムにマップします。 このマッピングは同じ機能を表していません。 たとえば、 TerminateThreadfinally 句を実行したり、リソースを解放したりしないため、防止できません。 ただし、 Thread.Abort はすべてのロールバック コードを実行し、すべてのリソースを回収し、 ResetAbortを使用して拒否できます。 機能について想定する前に、ドキュメントをよくお読みください。

Win32 で 共通言語ランタイムで
CreateThread スレッドと スレッド の組み合わせ ThreadStart
TerminateThread Thread.Abort
SuspendThread の Thread.Suspend
ResumeThread Thread.Resume
スリープ Thread.Sleep
スレッド ハンドルの WaitForSingleObject Thread.Join
ExitThread 同等の値はありません
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
同等の値はありません Thread.Name
同等の値はありません Thread.IsBackground
CoInitializeEx に近い (OLE32.DLL) Thread.ApartmentState

マネージド スレッドと COM アパートメント

マネージド スレッドは、 シングル スレッド または マルチスレッド アパートメントをホストすることを示すようにマークできます。 (COM スレッド アーキテクチャの詳細については、「プロセス、スレッド、およびアパートメント」を参照してください)。Thread クラスのGetApartmentStateSetApartmentState、およびTrySetApartmentStateメソッドは、スレッドのアパートメント状態を返して割り当てます。 状態が設定されていない場合、 GetApartmentStateApartmentState.Unknownを返します。

このプロパティは、スレッドが ThreadState.Unstarted 状態にある場合にのみ設定できます。このプロパティは、スレッドに対して 1 回だけ設定できます。

スレッドが開始される前にアパートメント状態が設定されていない場合、スレッドはマルチスレッド アパートメント (MTA) として初期化されます。 ファイナライザー スレッドと、 ThreadPool によって制御されるすべてのスレッドは MTA です。

Von Bedeutung

アプリケーションのスタートアップ コードの場合、アパートメントの状態を制御する唯一の方法は、エントリ ポイント プロシージャに MTAThreadAttribute または STAThreadAttribute を適用することです。

COM に公開されているマネージド オブジェクトは、フリー スレッド のマーシャラーを集計したかのように動作します。 言い換えると、任意の COM アパートメントからフリー スレッド方式で呼び出すことができます。 このフリー スレッド動作を示さないマネージド オブジェクトは、 ServicedComponent または StandardOleMarshalObjectから派生したオブジェクトだけです。

マネージド ワールドでは、コンテキストとコンテキストにバインドされたマネージド インスタンスを使用しない限り、 SynchronizationAttribute はサポートされません。 Enterprise Services を使用している場合、オブジェクトは ServicedComponent から派生する必要があります (オブジェクト自体は ContextBoundObjectから派生します)。

マネージ コードが COM オブジェクトを呼び出すときは、常に COM 規則に従います。 つまり、OLE32 によって指示された COM アパートメント プロキシと COM+ 1.0 コンテキスト ラッパーを介して呼び出されます。

ブロックの問題

スレッドがアンマネージド コードでスレッドをブロックしているオペレーティング システムに対してアンマネージド呼び出しを行った場合、ランタイムは Thread.Interrupt または Thread.Abortに対して制御を行いません。 Thread.Abortの場合、ランタイムはスレッドを Abort としてマークし、マネージド コードを再入力するときに制御します。 アンマネージド ブロックではなく、マネージド ブロッキングを使用することをお勧めしています。 WaitHandle.WaitOneWaitHandle.WaitAnyWaitHandle.WaitAllMonitor.EnterMonitor.TryEnterThread.JoinGC.WaitForPendingFinalizersなどはすべて、 Thread.InterruptThread.Abortに対応します。 また、スレッドがシングルスレッド アパートメント内にある場合、スレッドがブロックされている間、これらすべてのマネージド ブロッキング操作によってアパートメント内のメッセージが正しくポンプされます。

スレッドとファイバー

.NET スレッド モデルでは、 ファイバーはサポートされていません。 ファイバーを使用して実装されるアンマネージ関数を呼び出さないでください。 このような呼び出しにより、.NET ランタイムがクラッシュする可能性があります。

こちらも参照ください