Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

process

events

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 :-)

like image 964
Lars Udengaard Avatar asked Feb 28 '12 15:02

Lars Udengaard


People also ask

What is Process exited?

The Exited event indicates that the associated process exited. This occurrence means either that the process terminated (aborted) or successfully closed. This event can occur only if the value of the EnableRaisingEvents property is true .

What is EnableRaisingEvents?

The EnableRaisingEvents property is used in asynchronous processing to notify your application that a process has exited.


2 Answers

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.

like image 61
Daniel Avatar answered Oct 21 '22 23:10

Daniel


Apparently you have to listen to the StandardOutput stream if you redirected it, otherwise the Process will not exit. It waits for someone to read the output first.

Process.Exited event is not be called

like image 24
Lars Udengaard Avatar answered Oct 21 '22 23:10

Lars Udengaard