Windowsフォームアプリケーションのエントリポイント(詳しくは、「アプリケーションのエントリポイントを自作する」)には、STAThread属性が適用されているのが普通です。
''' <summary> ''' アプリケーションのメイン エントリ ポイントです。 ''' </summary> Module Program <STAThread()> _ Sub Main() Application.Run(New Form1()) End Sub End Module
/// <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の機能には、以下のようなものがあります。(下記の「参考」にあるページ等を参考にしました。)
実はVisual Studioのコード分析では、System.Windows.Forms名前空間を参照しており、MainメソッドにSTAThreadAttribute属性が付いていない場合、「Windows フォームのエントリ ポイントを STAThread でマークします」という警告が出ます。この警告の説明によると、STAThreadAttribute属性はWindowsフォームを使用するすべてのアプリケーションのエントリポイントに指定する必要があり、MTAはWindowsフォームでサポートされていないということです。
以上から、Windowsフォームアプリケーションでは、MainメソッドにSTAThreadAttribute属性が必要であると考えてよいでしょう。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。