2017-02-03 36 views
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()); 
+0

ほとんどのUIコンポーネント(COM)はThreaSafeではなく、MTA環境で正しく動作しません。 – codeteq

+0

スレッドSTAを宣言すると、スレッドをブロックせずにメッセージポンプを実行するという約束をします。 STAスレッドをブロックしたり、メッセージポンプを搭載していない場合は、ランダムに悪いことが起こる可能性があります。詳細については、[この回答](http://stackoverflow.com/a/4530773/80274)を参照してください。 –

+1

@ScottChamberlain Trueですが、 'Thread.Join' *はポンピング待ちです。呼び出し元がUIスレッドでなかった場合、これがうまくいくと思います。 – Luaan

答えて

1

私は呼び出し元のスレッドがハングします正確に何を見つけ出すことができなかった例では、私はopenfile- /セーブファイルダイアログを開くには、次の静的メソッドを使用しますSTAスレッドが終了するのを待っているときにjoin()を呼び出すことができますが、時にはうまく動作しないことがあります。 Finaly私は、Join()の代わりに

while (InvokeResult == DialogResult.None) Application.DoEvents(); 

を使用して解決することに決めました。

関連する問題