DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

STAThreadの意味は?

Windowsフォームアプリケーションのエントリポイント(詳しくは、「アプリケーションのエントリポイントを自作する」)には、STAThread属性が適用されているのが普通です。

VB.NET
コードを隠すコードを選択
''' <summary>
''' アプリケーションのメイン エントリ ポイントです。
''' </summary>
Module Program
    <STAThread()> _
    Sub Main()
        Application.Run(New Form1())
    End Sub
End Module
C#
コードを隠すコードを選択
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
    Application.Run(new Form1());
}

しかし、例えばMSDNの「フォームが開始時に非表示になるように設定する」のコードには、MainメソッドにSTAThreadAttribute属性が付いていません。STAThreadAttribute属性は本当に必要なのでしょうか?

STAThreadAttribute属性の意味については、MSDNの「STAThreadAttribute クラス」にあります。その説明は、「アプリケーションのCOMスレッドモデルがシングルスレッドアパートメント(STA: Single-Threaded Apartment)であることを示します」というものです。もしMainメソッドにSTAThreadAttribute属性を付けなかったならば、C#では、マルチスレッドアパートメント(MTA: multithreaded apartment)になります。ただしVB.NETでは、MainメソッドにSTAThreadAttribute属性を付けなくてもSTAになります。

STAとMTAについては、Wikipediaの「Component Object Model」の「COMのスレッド」に説明があります。簡単に言うと、STAは単一のスレッドでCOMを実行させるために必要で、それはWindowsのメッセージキューを利用して行われます。よってSTAでしか動作しないCOMはスレッドセーフではありませんが、MTAで動作するCOMは自分でスレッドの同期を取る必要があり、時にはスレッドをブロックします。

話を元に戻してMainメソッドにSTAThreadが必要かということで言うと、STAでしか動かないCOMを使用する場合は、必要ということになります(VB.NETの場合はデフォルトでSTAなので必要はありませんが、明示的に記述しておいた方がよいでしょう)。多くのCOM(特にユーザーインターフェース関係のCOM)はSTAでしか動作しないため、通常はCOMを使用する場合に必要になります。

自分でCOMを直接使っていないとしても、.NET Frameworkの一部の機能はCOMを使用しているため、そのような機能を使用する場合は、必ずSTAにする必要があります。STAでないと使用できない.NET Frameworkの機能には、以下のようなものがあります。(下記の「参考」にあるページ等を参考にしました。)

  1. ドラッグ&ドロップ機能
  2. クリップボード関係の機能
  3. OpenFileDialog、SaveFileDialogのようなFileDialogの派生クラスや、FolderBrowserDialogクラスによるダイアログの表示
  4. WebBrowserコントロール
  5. IMEの使用
  6. RichTextBoxコントロールの一部の機能(未確認)
  7. リフレクションを利用したメソッドの呼び出し(.NET Framework 1.0 のみ?)

実はVisual Studioのコード分析では、System.Windows.Forms名前空間を参照しており、MainメソッドにSTAThreadAttribute属性が付いていない場合、「Windows フォームのエントリ ポイントを STAThread でマークします」という警告が出ます。この警告の説明によると、STAThreadAttribute属性はWindowsフォームを使用するすべてのアプリケーションのエントリポイントに指定する必要があり、MTAはWindowsフォームでサポートされていないということです。

以上から、Windowsフォームアプリケーションでは、MainメソッドにSTAThreadAttribute属性が必要であると考えてよいでしょう。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。