Process.Exited 永远不会被调用,即使 EnableRaisingEvents 设置为 true [英] Process.Exited is never called, even though EnableRaisingEvents is set to true

查看:67
本文介绍了Process.Exited 永远不会被调用,即使 EnableRaisingEvents 设置为 true的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an executable, which runs fine when i run it manually, and it exists as it should with the expected output. But when i run it with the method bellow, the Process.Exited event is never fired. Notice that i have remembered the 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() 而不是反应式扩展来等待退出事件.

The problem is the same, if i use Process.WaitForExit() instead of reactive extensions, to wait for the exit event.

此外,如果我使用另一个参数运行该进程,该参数会产生另一个输出,则它存在正常.

Also, if i run the process with another argument, which produces another output, it exists fine.

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

It seems to have something to do with the process.StartInfo.RedirectStandardOutput = true; since when i disable this, it works. But that could just be a symptom of another problem.

感谢任何帮助:-)

推荐答案

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

There's a deadlock in your code. 'Standard output' is just a kind of named pipe, which has a small buffer to transfer data from one process to the other. If the buffer is full, the writing process has to wait for the reading process to retrieve some data from the buffer.

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

So the process you have started might wait for you to read from the standard output, but you are waiting for the process to finish before you start reading -> deadlock.

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

The solution is to read continuously while the process is running - just call StandardOutput.ReadToEnd() before you call WaitForExit(). If you want to read without blocking the current thread, you can use BeginOutputReadLine() and the OutputDataReceived events.

这篇关于Process.Exited 永远不会被调用,即使 EnableRaisingEvents 设置为 true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆