即使EnableRaisingEvents设置为true,也永远不会调用Process.Exited

时间:2012-02-28 15:11:32

标签: c# events process

我有一个可执行文件,当我手动运行它时运行正常,并且它应该与预期输出一样存在。但是当我使用下面的方法运行它时,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;有关,因为当我禁用它时,它可以工作。但这可能只是另一个问题的症状。

感谢任何帮助: - )

2 个答案:

答案 0 :(得分:6)

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

因此,您已启动的过程可能会等待您从标准输出中读取,但您在开始阅读之前等待该过程完成 - >死锁。

解决方案是在流程运行时继续阅读 - 只需在致电StandardOutput.ReadToEnd()之前致电WaitForExit()。 如果您想在不阻止当前主题的情况下阅读,可以使用BeginOutputReadLine()OutputDataReceived个事件。

答案 1 :(得分:1)

显然,如果重定向它,则必须侦听StandardOutput流,否则Process将不会退出。它等待某人先读取输出。

Process.Exited event is not be called