STAThread 対 MTAThread (WHorst)
最近遭遇したスレッドの問題を皆さんにご紹介しましょう。私と同じ目に遭う人を減らせるかもしれません。
ここで、だれかが書いた C# アプリケーションを例とし、ここでは "DeltaEngine" と呼ぶことにします。DeltaEngine はネイティブ アセンブリを呼び出し、そこから特定のイベントを処理します。
DeltaEngine をライブラリ プロジェクトとして参照するソリューションを作成し、VB プロジェクトからこのプロジェクトを呼び出しました。このプロジェクトの名前を "VBApp" とすると、参照構造は次のようになります。
VBApp (VB) -> DeltaEngine (C#) -> NativeCode
VBApp をスタートアップ プロジェクトとして使用してソリューションを実行したとき、ネイティブ コードから DeltaEngine がイベントを取得するのをいつまでも待たされました。しかし、DeltaEngine をスタートアップ プロジェクトとしてまったく同じ呼び出しを実行した場合、予想どおりにイベントを処理することがわかりました。この問題を解決するために長時間を費やしたあげく、お手上げとなったのです。
最終的に、C# プロジェクトは既定でマルチ スレッド アパートメント (MTA) を使用するのに対し、VB プロジェクトは既定でシングル スレッド アパートメント (STA) を使用することを人から指摘されました。DeltaEngine はもともと C# プロジェクトのスタートアップ アプリケーションとして作成されたため、MTA スレッドを前提としていたのです。VB スタートアップ プロジェクトからこのコードの呼び出しを開始したとき、それとは知らずに STA スレッドで実行していたわけです。これが原因で、DeltaEngine コードはイベントの発生後もイベントを待機し、いつまでも待機し続けることになってしまいました。DeltaEngine をスタートアップ プロジェクトとして設定して、同じ呼び出しを実行すると、MTA スレッドを使用するために予想どおりに動作するのです。
解決方法は、VBApp の Sub Main に MTAThreadAttribute を追加することでした。その後は正常に動作するようになりました。
<MTAThread> Sub Main()
同様に、STAThread 属性を C# の Main メソッドで使用する場合、コードは次のようになります。
[STAThread]
static void Main()
Windows フォームは STA スレッドを必要とするため、C# Windows アプリケーションを作成する場合、このようなコードを Program.cs に使用することになります。
STAThread および MTAThread に関するドキュメントは既存のものがあるので、詳細については次のリンクのドキュメントを参照してください。
STAThreadAttribute
https://msdn2.microsoft.com/ja-jp/library/system.stathreadattribute(VS.71).aspx
https://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx (英語)
MTAThreadAttribute
https://msdn2.microsoft.com/ja-jp/library/system.mtathreadattribute(VS.71).aspx
- VB IDE テスト、Bill Horst
投稿 : 2008 年 3 月 24 日 12:47 PM
分類 : Bill Horst
VB チームの Web ログ - https://blogs.msdn.com/vbteam/archive/2008/03/24/stathread-vs-mtathread-whorst.aspx (英語) より