MS_STA - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
-
STA : Single-Threaded Apartment
-
マルチスレッド・クライアントにスレッドセーフなアクセスを提供する仕組み。
-
1スレッドだけ所属できるアパートメント
-
アパートメント属性はスレッドに対して設定される。
-
単一のスレッドのアクセスだけを想定しているオブジェクト。
-
単一のスレッドだけオブジェクトにアクセスすることが保障される。
-
スレッド毎にメンバ変数をコピーすることで実現する。
-
メンバ変数は、生成した COM をスレッドの
Thread Local Storage (TLS) 上にコピーされる。 -
また、他のスレッドから呼び出される場合、
Windowsメッセージキュー を使用した
スレッド間マーシャリング(Proxy・Stub)で直列化される。
補足(「メンバ変数をコピーする」の読み解き): この説明は
一部のケースを述べたものなので、全体像を補っておく。【STA の本質は「1 つのスレッドに固定する」こと】★ ・STA に属する COM オブジェクトは、 【生成したスレッドの上でしか実行されない】 ・他スレッドから呼ぶと → Proxy が【メッセージをポストする】 → 所有スレッドのメッセージ ループが受け取り、 そのスレッドが実際のメソッドを実行する ★ → 結果として【直列化される】 → だから「スレッドセーフに書かなくてよい」 (常に同じ 1 スレッドしか触らないため) 【原文の「TLS にコピー」について】 ・これは【スレッドごとに別インスタンスを持つ】 パターン(ThreadingModel=Apartment で 各 STA が自分のインスタンスを持つ場合)の説明 ・COM の ThreadingModel には Apartment … STA。スレッドごとに隔離される ★ Free … MTA。呼び出し側が同期責任を負う Both … 呼び出し側のアパートメントに従う Neutral … NA(COM+ 由来。切り替えコストが小さい) があり、挙動が変わる【STA の最大の落とし穴:メッセージ ループが必要】★ ・STA スレッドは 【メッセージ ポンプを回していないと 他スレッドからの呼び出しを処理できない】 → ワーカー スレッドを STA にして Application.Run() を回していないと 呼び出しが【永久にブロックする】★ ・「Excel を自動化したら固まる」の典型原因 → UI スレッド(STA)が Thread.Sleep / .Result で【止まっている】 → メッセージが処理されず、COM 呼び出しが返らない → 【デッドロック】
補足(.NET から見た STA / MTA): 実務で意識するのは
属性 1 つとスレッド生成時の指定である。【.NET でのアパートメント指定】★ ・エントリ ポイント [STAThread] … 【Windows Forms / WPF は必須】★ [MTAThread] … コンソール既定(.NET Framework) ・自分で作るスレッド var t = new Thread(Work); t.SetApartmentState(ApartmentState.STA); // 開始前に t.Start(); ・【スレッド プールのスレッドは常に MTA】★ → Task.Run の中で STA が要る COM を触ると壊れる → 専用の STA スレッドを立てる必要がある 【なぜ Windows Forms / WPF は STAThread が要るのか】 ・クリップボード、ドラッグ&ドロップ、 OLE、コモン ダイアログが【COM の STA 前提】だから → 外すと「現在のスレッドは シングル スレッド アパートメント モードで なければなりません」という例外になる ★【.NET Core 以降】 ・[STAThread] は【今も有効】(Windows 上) ・コンソール アプリの既定は .NET Core 以降【MTA】 ・非 Windows では SetApartmentState が 【PlatformNotSupportedException】を投げる ★
-
STA と MTA
http://eternalwindows.jp/com/apartment/apartment01.html -
COMにおけるアパートメントの概要 - イグトランスの頭の中
http://dev.activebasic.com/egtra/2014/12/10/703/ -
Single-Threaded Apartments - Windows applications | Microsoft Docs
https://learn.microsoft.com/en-us/windows/win32/com/single-threaded-apartments
移行メモ(自己リンク): 移行元の参考 1 件目は
[[STA]]と[[MTA]]と自ページへのリンクを含んでいたため、
リンクを外してテキストにした。
Tags: 移行, Windows, プログラミング, .NET開発