Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
706 views
in Technique[技术] by (71.8m points)

c# - Process.Exited is never called, even though EnableRaisingEvents is set to true

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();;
}

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.

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.

Any help is appreciated :-)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...