是否有任何asynchronous的Process.Start?
就像标题所暗示的那样,是否有等同于Process.Start
(允许您运行另一个应用程序或batch file),我可以等待?
我正在玩一个小的控制台应用程序,这似乎是一个完美的地方,使用asynchronous和等待,但我找不到这种情况下的任何文档。
我在想什么是这样的:
void async RunCommand() { var result = await Process.RunAsync("command to run"); }
Process.Start()
只启动进程,它不会一直等到完成,所以将其设置为async
没有什么意义。 如果你仍然想这样做,你可以做一些像await Task.Run(() => Process.Start(fileName))
。
但是,如果要asynchronous等待该过程完成,则可以使用与TaskCompletionSource
一起的Exited
事件 :
static Task RunProcessAsync(string fileName) { // there is no non-generic TaskCompletionSource var tcs = new TaskCompletionSource<bool>(); var process = new Process { StartInfo = { FileName = fileName }, EnableRaisingEvents = true }; process.Exited += (sender, args) => { tcs.SetResult(true); process.Dispose(); }; process.Start(); return tcs.Task; }
这是我的基础上svick的答案 。 它增加了输出redirect,退出代码保留以及稍微更好的error handling(即使无法启动,也可以部署Process
对象):
public static async Task<int> RunProcessAsync(string fileName, string args) { using (var process = new Process { StartInfo = { FileName = fileName, Arguments = args, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }, EnableRaisingEvents = true }) { return await RunProcessAsync(process).ConfigureAwait(false); } } private static Task<int> RunProcessAsync(Process process) { var tcs = new TaskCompletionSource<int>(); process.Exited += (s, ea) => tcs.SetResult(process.ExitCode); process.OutputDataReceived += (s, ea) => Console.WriteLine(ea.Data); process.ErrorDataReceived += (s, ea) => Console.WriteLine("ERR: " + ea.Data); bool started = process.Start(); if (!started) { //you may allow for the process to be re-used (started = false) //but I'm not sure about the guarantees of the Exited event in such a case throw new InvalidOperationException("Could not start process: " + process); } process.BeginOutputReadLine(); process.BeginErrorReadLine(); return tcs.Task; }