MS_MTA - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

MTA

概要

  • MTA : Multithreaded Apartment

  • スレッドセーフではないが、性能を追求した実装が可能な仕組み
    (...と言うか STA と比べて、何もしていないダケ)。

詳細

MTAのアパートメント

  • 複数スレッドが所属できるアパートメントで、プロセスに 1 つで共有される。

  • アパートメント属性はスレッドに対して設定される。

MTAのオブジェクト

  • 複数からのスレッドのアクセスを想定しているオブジェクト。

  • 複数のスレッドからのアクセスに備えてスレッドセーフに実装する必要がある。

MTAの仕組み

  • 特に特殊な実装をしない、一般的なオブジェクト。

  • マルチスレッド・クライアントから利用される場合、
    メンバ変数へのアクセス部分をスレッドセーフに実装する必要がある。

補足(「何もしていないダケ」は的確だが、一点だけ違う): この評価は
実装者から見れば正しいが、COM ランタイムの側では仕事をしている

【MTA でも COM が面倒を見ること】★
   ・【同じ MTA 内での呼び出し】
       → Proxy を挟まない【直接呼び出し】
       → 原文の言う「何もしていない」はここ ★
   ・【MTA から STA への呼び出し】
       → Proxy を作り、メッセージをポストする
   ・【STA から MTA への呼び出し】
       → RPC のスレッド プールから
         MTA のスレッドを 1 つ選んで実行する ★
       → つまり「どのスレッドで動くか分からない」

【MTA スレッドはメッセージ ループが不要】
   → STA と違い、Application.Run を回す必要がない
   → その代わり【自分でロックを掛ける責任】を負う

補足(STA と MTA の使い分け): 判断の指針を表にしておく。

STA MTA
所属できるスレッド 1 つだけ 複数(プロセスに 1 つ)
呼び出しの直列化 COM が行う 行わない
スレッドセーフの責任 不要(COM が保証) 実装者が負う
メッセージ ループ 必要 不要
性能 直列化のコストがある 速い
典型的な用途 UI、Office 自動化 サーバ側の処理
【実務での判断】★
   ・【UI を持つ】 → STA 一択
   ・【Office / Shell / OLE を触る】 → STA
   ・【ASP.NET / サービスで大量処理】 → MTA
     ただし対象 COM が Apartment モデルなら
     結局 STA が作られて直列化される
     → 【スループットが出ない】原因になる ★
     → 対象コンポーネントの ThreadingModel を確認する

   ・ASP.NET Web Forms の
     【<%@ Page AspCompat="true" %>】は
     「そのページを STA スレッドで実行する」指定
     → 古い COM を呼ぶための互換スイッチであり、
       【性能を大きく落とす】★
【.NET でありがちな誤解】
   「MTA だからスレッドセーフ」ではない。
   正しくは
     【MTA = COM が同期してくれない】★
     → 自分で lock する
     → あるいは【そもそも共有しない】
       (スレッドごとにインスタンスを作る)

参考

移行メモ(自己リンク): 移行元の参考 1 件目は
[[STA]]と[[MTA]]自ページへのリンクを含んでいたため、
リンクを外してテキストにした。


Tags: 移行, Windows, プログラミング, .NET開発

⚠️ **GitHub.com Fallback** ⚠️