現象
MTAThread設定時に、OpenFileDialogを実行すると下記エラーが発生する。
「System.Threading.ThreadStateException’OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。Main 関数に STAThreadAttribute が設定されていることを確認してください。 この例外はデバッガーがプロセスにアタッチされている場合にのみ発生します。」
エラーが発生するコード
static class Program
{
/// アプリケーションのメイン エントリ ポイントです。
[MTAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
private void Button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
//省略
}
}

原因
OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていないと発生する。
対策
対策済みコード
private void Button2_Click(object sender, EventArgs e)
{
OpenFileDialog frm = new OpenFileDialog();
DialogResult ret = STAShowDialog(frm);
if (ret == DialogResult.OK)
{
//省略
}
}
///
private DialogResult STAShowDialog(OpenFileDialog dialog)
{
DialogState state = new DialogState();
state.dialog = dialog;
System.Threading.Thread t = new System.Threading.Thread(state.ThreadProcShowDialog);
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
t.Join();
return state.result;
}
/// <summary>
/// バックグラウンドスレッドでFileDialog.ShowDialogを呼び出すために状態と戻り値を保持するクラス
/// </summary>
public class DialogState
{
public DialogResult result;
public OpenFileDialog dialog;
public void ThreadProcShowDialog()
{
result = dialog.ShowDialog();
}
}
コメント