【问题标题】:Process.Exited is never called, even though EnableRaisingEvents is set to trueProcess.Exited 永远不会被调用,即使 EnableRaisingEvents 设置为 true
【发布时间】:2012-02-28 15:11:32
【问题描述】:

我有一个可执行文件,当我手动运行它时它运行良好,并且它存在于预期的输出中。但是当我用下面的方法运行它时, Process.Exited 事件永远不会被触发。请注意,我记得 Process.EnableRaisingEvents

protected override Result Execute(RunExecutable task)
{
    var process = new Process();
    process.StartInfo.Arguments = task.Arguments;
    process.StartInfo.FileName = task.ExecutablePath;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.EnableRaisingEvents = true;

    process.Exited += (sender, args) =>
    {
        processSync.OnNext(new Result
        {
            Success = process.ExitCode == 0,
            Message = process.StandardOutput.ReadToEnd()
        });
        processSync.OnCompleted();
    };
    process.Start();

    return processSync.First();;
}

问题是一样的,如果我使用 Process.WaitForExit() 而不是响应式扩展,来等待退出事件。

另外,如果我使用另一个参数运行该过程,从而产生另一个输出,它就可以正常存在。

这似乎与process.StartInfo.RedirectStandardOutput = true; 有关,因为当我禁用它时,它可以工作。但这可能只是另一个问题的征兆。

任何帮助表示赞赏:-)

【问题讨论】:

    标签: c# events process


    【解决方案1】:

    您的代码中存在死锁。 “标准输出”只是一种命名管道,它有一个小的缓冲区来将数据从一个进程传输到另一个进程。如果缓冲区已满,则写入进程必须等待读取进程从缓冲区中检索一些数据。

    所以你已经开始的进程可能会等待你从标准输出中读取,但是你正在等待进程完成后再开始读取 -> 死锁。

    解决方案是在进程运行时连续读取 - 只需在调用 WaitForExit() 之前调用 StandardOutput.ReadToEnd()。 如果你想在不阻塞当前线程的情况下读取,可以使用BeginOutputReadLine()OutputDataReceived 事件。

    【讨论】:

    • 啊,这就解释了!谢谢:-)
    【解决方案2】:

    显然,如果您重定向它,您必须收听 StandardOutput 流,否则进程将不会退出。它等待有人先读取输出。

    Process.Exited event is not be called

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-12
      • 2012-10-27
      • 2013-10-12
      • 2012-03-27
      • 2013-08-29
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多