2016-05-17 16 views
0

コンソールアプリケーションでは、Windows 10、Visual Studio 2015、.NET 4.6では、TestProcessというMainの単一メソッドを呼び出します。私は、デバッグなしでアプリケーションを実行する場合のモードデバッグを構築し、それが正しいテキストを出力します。Visual Studioのデバッグ - System.Diagnostics.ProcessがWaitForExitでハングアップ

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press any key to continue . . .

私はデバッグでアプリケーションを実行する場合は、これが本当の問題だけの単純化である

Error False False False '' ''

を印刷する前に、3秒間待機し、このコードは、md5sums.exeのデバッグなしでリリースでハングするいくつかの複雑なコードのバックボーンですが、他のプログラムでも動作します。 Coplexコードもまたハングしますvar a = proc.WaitForExit(timeout);添付の例のようにタイムアウトまで。一方、この単純化は、デバッガなしでリリースで動作します。また、この問題はすべてWindows 10から始まりました.Windows 7では問題なく動作しました。

[編集]なぜmd5sums.exeが問題を引き起こし、何か他のものを使用するとわかりません。 FileName = "ping"、引数= "localhost"はすべて正常に動作します。

[EDIT2]私の複雑なプログラムは、Windows 10(リリース - デバッグなしで実行します)上で動作を停止しますが、この例では、Windows 7上でハング - 3つの漁獲がにありました

 static void TestProcess() 
     { 
      using (var proc = new Process()) 
      { 
       proc.StartInfo.FileName = "md5sums.exe"; 
       proc.StartInfo.WorkingDirectory = @"C:\Temp\ProcessDebug"; 
       proc.StartInfo.Arguments = "-u test.txt"; 
       proc.StartInfo.CreateNoWindow = true; 
       proc.StartInfo.UseShellExecute = false; 
       proc.StartInfo.RedirectStandardOutput = true; 
       proc.StartInfo.RedirectStandardError = true; 
       StringBuilder output = new StringBuilder(); 
       StringBuilder error = new StringBuilder(); 
       using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) 
       using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false)) 
       { 
        proc.OutputDataReceived += (sender, e) => 
        { 
         if (e.Data == null) 
          outputWaitHandle.Set(); 
         else 
          output.AppendLine(e.Data); 
        }; 
        proc.ErrorDataReceived += (sender, e) => 
        { 
         if (e.Data == null) 
          errorWaitHandle.Set(); 
         else 
          error.AppendLine(e.Data); 
        }; 
        proc.Start(); 
        proc.BeginOutputReadLine(); 
        proc.BeginErrorReadLine(); 
        var timeout = 1000; 
        var a = proc.WaitForExit(timeout); 
        var b = outputWaitHandle.WaitOne(timeout); 
        var c = errorWaitHandle.WaitOne(timeout); 
        if (a && b && c) 
         Console.WriteLine(output.ToString()); 
        else 
         Console.WriteLine($"Error {a} {b} {c} '{output}' '{error}'"); 
       } 
      } 
     } 
+0

この問題は、非常に簡単な解決策です。 *意味のある*エラーメッセージを書くときにしか発見できません。プログラムのユーザーに正確に何が間違っていたかを示すヒントです。経験則では、ワークステーションPCでは10秒未満、サーバーでは20秒未満のタイムアウトを使用してはなりません。それが "複雑な"プログラムであれば、さらに追加してください。 –

+0

@HansPassantコンプレックスプログラムのタイムアウト時間は20秒です。この例では20秒のタイムアウトは動作を変更しませんでしたが、test.txtは短い1行のテキストファイルとConsole.WriteLine($ "Error: '{error.ToString ()} '、' {output.ToString()} '"); "エラー: ''、 '' |、a、b、cは失敗したときにすべてfalseになります。 – watbywbarif

+1

@watbywbarif VSホスティングプロセスを無効にして、何が起こるかを確認してください。 https://msdn.microsoft.com/en-us/library/ms185330.aspx –

答えて

1

(デバッグデバッグを実行します)この問題を解決:私の設定で起動すると、いくつかのケースで

  • md5sums.exeは、完成後に実行を一時停止します:

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press ENTER to exit

これは、CreateNoWindowがfalseに設定され、stdout、stderrリダイレクトが削除された場合に発生します。これは、-eスイッチを使用して修正できます。'すぐに終了します。 「」を返す前に一時停止しないでください。これにより、すべてのケースが修正されます。しかし、私は使用しませんでした - 私はデバッガとWindowsのバージョンに応じて一貫性のない動作があった。

  • デバッグなしで実行すると、すべての設定が同じであっても「一時停止」は実行されず、「終了するにはEnterを押します」が出力されませんでした。しかし、デバッグを実行すると、プログラムがタイムアウトするまで一時停止し、md5sumsがEnterを待っているタスクマネージャでハングすることになりました。
  • リリースモードでは、デバッグなしで実行されますが、一時停止が発生し、「終了するにはEnterを押してください」がWindows 7の出力にありました。md5sumsが返され、実行がブロックされずにタイムアウトになりました。これは、md5sumsがEnterを待つタスクマネージャーに住んでいて、タイムアウトした後にプログラムが続行されるWindows 10ではそうではありませんでした。
関連する問題