1

C#アプリ内で、次のようなプロセスを定義して起動します。

        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.WorkingDirectory = "Resources/";
        startInfo.FileName = "batch.exe";
        startInfo.CreateNoWindow = true;
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.Arguments = "-h usb -o read";

        Process process = new Process();
        process.StartInfo = startInfo;
        process.EnableRaisingEvents = true;
        process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);

        process.Start();
        process.BeginOutputReadLine();
        process.WaitForExit();
        process.CancelOutputRead();
        process.Close();

このプロセスにDataReceivedEventを使用して、出力を保存しています。

void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != String.Empty && e.Data != null)
        {
            //Save data 
            result.Add(e.Data);

            if (progressbar.InvokeRequired)
                progressbar.Invoke(new ThreadStart(() =>
                {
                    progressbar.PerformStep();
                }));
            else
                progressbar.PerformStep();
        }
    }

同時に、DataReceivedイベントが発生するたびに、プログレスバーを更新したいと思います。プログレスバーを呼び出すコードの何が問題になっているのかわかりませんが、スレッドが処理されることはなく、エラーをスローせずにコードのその部分に到達すると、アプリがロックされます(Visual Studioでのデバッグ中)。これを正しくする方法について何かアイデアはありますか?ありがとう!

4

1 に答える 1

2

メインスレッドが同期プロセスでスタックしています。WaitForExit()呼び出し-一般的なデッドロック。process_OutputDataReceivedは別のスレッドで実行されますが、Invokeは返されません-メインスレッドはWaitForExitによってブロックされます。

同期WaitForExit呼び出しを削除し、Process.Exitedイベントをサブスクライブして、そこですべてのクリーンアップを機能させます。

于 2012-08-27T15:11:54.917 に答える