Asynchronous method in a C# class that executes a process

倾然丶 夕夏残阳落幕 提交于 2019-12-06 10:41:16
  1. You don't need the async on your method signature, because you don't use await. It's enough to return a Task. The caller may await that Task - or not, it has nothing to do with your method.

  2. Don't use the async keyword on that lambda and don't use the asynchronous ReadToEnd inside that lambda. It's hard to predict what happens if you return from that event handler before it's really finished. And anyway you want to finish that method. It's called when the process exited, there is no need to make this async.

  3. Here it's the same as in (2). I think it's ok to do this "synchronously" inside this event handler. It will only block this handler, but the handler is called after the process has exited, so I guess it's ok for you.

  4. Your exception handling looks OK, but I would add another try/catch block inside the Exited event handler. But that's not based on knowledge, rather on experience that everywhere something can go wrong :)


For a better way to get the standard and error output, I suggest to subscribe to the ErrorDataReceived and OutputDataReceived events and fill StringBuilders with the received data.

In your method, declare two StringBuilders:

StringBuilder outputBuilder = new StringBuilder();
StringBuilder errorBuilder = new StringBuilder();

And subscribe to the events right after you instantiated process:

process.OutputDataReceived += (sender, e) => outputBuilder.AppendLine(e.Data);
process.ErrorDataReceived += (sender, e) => errorBuilder.AppendLine(e.Data);

Then you only need to call these two methods right after you called process.Start() (it won't work before, because the stdout and stderr are not yet opened):

process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();

In your Exited event handler you can then call outputBuilder.ToString() (or errorBuilder.ToString() respectively) instead of ReadToEnd and everything should work fine.

Unfortunatly there is a drawback, too: if the process is very very fast, your Exited handler may theoritically be called before those Begin*ReadLine calls. Don't know how to handle that, but it's not very likely to happen.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!