スレッドの初期アパートメントは不定
.NETの一般的なWindowsFormsアプリケーションのエントリポイントは、STAThreadAttributeが宣言されており、"single-threaded apartment"(以降STA)のCOMスレッディングモデルが選択される。
Visual Studio 2005 Professional 英語版で自動生成されたエントリポイント
static class Program { ////// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } }
なので、アプリケーション中でスレッド(Thread)を生成した場合も自動的にSTAになると思いこんでいたのだが、たまたまCOMコンポーネント(WebBrowser Component)を使った所でThreadStateExceptionを吐いたので、スレッド生成後のApartmentStateプロパティを確認したら"Unknown"と表示される。やはり、スレッド生成時にはエントリポイントのApartmentStateは引き継いでくれないのね。
ということで、生成した先でCOMコンポーネントを使う可能性のあるスレッドは、該当のCOMコンポーネントに適した(大抵はSTAだろうけど)アパートメントの指定を、明示的に指定しないと駄目みたい。
スレッド生成時にApartmentStateを設定する(.NET2.0)
Thread worker = new Thread(new ThreadStart(this.ExecuteHandler)); worker.SetApartmentState(ApartmentState.STA); 〜
なお、ApartmentStateプロパティは.NET2.0の時点で"Obsolete"。個人的にはスレッドアパートメントモデルなんて面倒なものは早々に消えて欲しい。...でも、一度バイナリとして放たれたCOMコンポーネントがそう簡単に使えなくなる訳にもいかないのだろうな。