2016-08-03 15 views
0

フォームを開いたときに外部プログラムを開く次のコードでwinformがあります。プログラムが終了すると、ボタンがクリックされたことを返すためのオプションがポップアップされたダイアログボックスが表示されます。これにより、ダイアログボックスが閉じて初期フォームに戻り、関数を実行して外部プログラムを再度開きます。ShowDialog()は、元のフォームをクリック可能にしないようにしていません。

ここに問題があります。元のフォームはSTILLクリック可能であり、機能は実行されていません。何か案は?

public Manager() 
    { 
     InitializeComponent(); 
     ExternalProgramOpen(); 

    } 

    private void ExternalProgramOpen() 
    { 
     Process startProgram = Process.Start("program.exe", Program.ConnectionArg); 
     startProgram.EnableRaisingEvents = true; 
     startProgram.Exited += this.PrematureClose; 
    } 

    private void PrematureClose(object sender, EventArgs e) 
    { 
     ManagerWarning messagepopup = new ManagerWarning(); 
     messagepopup.ShowDialog(); 
     using (var ManagerWarning = new ManagerWarning()) 
     { 
      if (ManagerWarning.ShowDialog() == DialogResult.Retry) 
      { 
       ExternalProgramOpen(); 
      } 
     } 
    } 
+0

は、ワーカースレッドにそれはダイアログを超えてモーダルされていないと厄介な問題の多くをUIを表示することはありません。簡単な回避策は、 'startProgram.SynchronizingObject = this;'を追加することです。 –

+1

'PrematureMethod'もコンパイルするべきかどうかはわかりません。投稿したコードが実行中のコードであると確信していますか? 2つの連続するモーダルダイアログを作成して表示しています.1つは 'using'ステートメントの外側に、もう1つはインスタンス名としてクラス名を使用しています...明らかに間違ったことをしています。 – InBetween

+0

これはうまくコンパイルされました。これで 'invoke'コードが追加され、ダイアログボックスのボタンがクリックされている部分を除いて、やるべきことが実行されます。 –

答えて

2

この効果の理由はExitedイベントがプロセスを開始したのと同じUIスレッドで提起されていないだろうということです。

別のスレッドからShowDialog()を呼び出すと、新しいウィンドウは使用されず、元のUIスレッドをブロックします。 、この問題を解決InvokeRequiredtrueあるかどうかを確認してInvokeを使用するには

private void PrematureClose(object sender, EventArgs e) 
{ 
    if (InvokeRequired) 
    { 
     Invoke(new Action(() => PrematureClose(sender, e))); 
     return; 
    } 

    // your code here 
    // ... 
} 
+0

これを今すぐテストしていただきありがとうございます。 –

+0

フォームは同じスレッド内にあるだけでなく、同じプロセスでもありません* – Servy

+0

@ServyはOPの質問を誤解するかもしれませんが、私には_other_プロセスがすでに終了していて、元のプロセス。彼が話しているフォームは、元のプロセスと同じで、終了したプロセスではないようです。 –

関連する問題