-2

I've the following code from an answer in: Process.start: how to get the output?

static void runCommand() {
    //* Create your Process
    Process process = new Process();
    process.StartInfo.FileName = "cmd.exe";
    process.StartInfo.Arguments = "/c DIR";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    //* Set your output and error (asynchronous) handlers
    process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
    process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
    //* Start process and handlers
    process.Start();
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();
    process.WaitForExit();
}
static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) {
    //* Do your stuff with the output (write to console/log/StringBuilder)
    Console.WriteLine(outLine.Data);
}

In my case I need to call multiple instances at the same time, I was thinking in making Threads but I understand that there is no need of threads with this code. Could someone explain me the difference and if is necessary make a thread doing async calls?
Thanks in advance. Kind regards

Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
  • 1
    `I understand that there is no need of threads with this code` So, since you understand that, why are you asking this question? – Servy Sep 11 '17 at 15:28
  • Because I don't understand the difference. Thanks for your help. – Leandro Bardelli Sep 11 '17 at 16:06
  • If you don't understand the difference then why did you say that you understand the difference? – Servy Sep 11 '17 at 16:07
  • Thanks for your help. – Leandro Bardelli Sep 11 '17 at 16:07
  • 1
    The `Process` class is inherently asynchronous, as the process you start is completely independent of your own process. If you redirect output, it's no longer completely independent, but handling I/O asynchronously is well-documented, including with `TextReader`. The only thing left is notification of process exit, which you can implement either by just detecting the end of the output streams (i.e. `StandardOutput.ReadLineAsync()` and `StandardError.ReadLineAsync()` both have returned `null`), or wrapping `Exited` with `TaskCompletionSource` (see marked duplicate). – Peter Duniho Sep 11 '17 at 16:10
  • Thanks for your help @PeterDuniho, I'll check that link! – Leandro Bardelli Sep 11 '17 at 16:12

2 Answers2

0

if you want to run your processes in parallel, you have to slightly change your code. The line "process.WaitForExit();" is not what you want (per your description)

See the MSDN:

WaitForExit() makes the current thread wait until the associated process terminates. It should be called after all other methods are called on the process. To avoid blocking the current thread, use the Exited event.

So if you want to execute multiple instances of this for example inside the loop, do not block your main thread (that creates additional cmd processes) with waiting.

Bobo
  • 335
  • 2
  • 10
0

If you need to run multiple invocations you'll have to use another strategy since WaitForExit() is going to block.

If you don't need to know when completion has occured simply remove WaitForExit() as you don't need a synchronization context.

If you need to know when the processes have completed, then threading is an option, however, spawning a thread and process for many is inefficient - you could leverage the Process Exit Event with some housekeeping to track completion instead, and emit your own event to signal conclusion.

RamblinRose
  • 4,883
  • 2
  • 21
  • 33