0
Windowsフォームアプリケーションでダイアログボックスを使用するには、メインスレッドを[STAThread]
に設定するか、ダイアログボックスを実行するために別のSTAスレッドを作成する必要があります。ダイアログボックスのSTAスレッド
私は本当に理解できなかった問題がここにあります。開始されたSTAスレッドは「時には」終了しないので、メインスレッドはJoin()でハングアップし続けます。
t.Join()
の代わりにApplication.DoEvents()
を使用して解決しましたが、現在は問題なく動作しているようですが、「時々」に依存しています。
using System.Windows.Forms;
namespace Dialog
{
public class clsDialogState
{
public DialogResult result;
public FileDialog dialog;
public void ThreadProcShowDialog()
{
result = DialogResult.None;
result = dialog.ShowDialog();
}
}
public static class clsShowDialog
{
public static DialogResult STAShowDialog(FileDialog dialog)
{
clsDialogState state = new clsDialogState();
state.dialog = dialog;
System.Threading.Thread t = new System.Threading.Thread(state.ThreadProcShowDialog);
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
//t.Join(); //Main thread might hang up here
while (state.result == DialogResult.None) Application.DoEvents(); //Everything is refreshed/repainted fine
return state.result;
}
}
}
ので、使い方は単にある:
Dialog.clsShowDialog.STAShowDialog(new SaveFileDialog());
ほとんどのUIコンポーネント(COM)はThreaSafeではなく、MTA環境で正しく動作しません。 – codeteq
スレッドSTAを宣言すると、スレッドをブロックせずにメッセージポンプを実行するという約束をします。 STAスレッドをブロックしたり、メッセージポンプを搭載していない場合は、ランダムに悪いことが起こる可能性があります。詳細については、[この回答](http://stackoverflow.com/a/4530773/80274)を参照してください。 –
@ScottChamberlain Trueですが、 'Thread.Join' *はポンピング待ちです。呼び出し元がUIスレッドでなかった場合、これがうまくいくと思います。 – Luaan