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


http://msdn2.microsoft.com/ja-jp/library/system.stathreadattribute(VS.71).aspx


http://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx (英語)


MTAThreadAttribute


http://msdn2.microsoft.com/ja-jp/library/system.mtathreadattribute(VS.71).aspx


– VB IDE テスト、Bill Horst


VB チーム


投稿 : 2008 3 24 12:47 PM


分類 : Bill Horst

VB ムの Web ログ – http://blogs.msdn.com/vbteam/archive/2008/03/24/stathread-vs-mtathread-whorst.aspx (英語) より


Comments (0)