Код, который вы написали в форме, которую вы написали, является (почти) нормальным: process.Start Запустите процесс, который вы укажете, ну, в общем, другой процесс, так что чтение вашего выходного потока будет происходить параллельно с выполнением вашего процесса.Одна проблема, однако, заключается в том, что вы должны добавить вызов process.WaitForExit в конце концов - тот факт, что выходной поток закрыт, не означает, что процесс завершен.
Однако у вас возникнут проблемы с синхронным чтением, если выпопробуйте прочитать как stdout, так и stderr процесса: нет способа прочитать 2 потока синхронно и одновременно - вы зашли в тупик, если вы читаете stdout, а процесс записывает в stderr и ждет, пока вы используете его вывод, или наоборот.
Чтобы обеспечить это, вы можете подписаться на OutputDataReceded и ErrorDataRectained, например:
type ProcessResult = { exitCode : int; stdout : string; stderr : string }
let executeProcess (exe,cmdline) =
let psi = new System.Diagnostics.ProcessStartInfo(exe,cmdline)
psi.UseShellExecute <- false
psi.RedirectStandardOutput <- true
psi.RedirectStandardError <- true
psi.CreateNoWindow <- true
let p = System.Diagnostics.Process.Start(psi)
let output = new System.Text.StringBuilder()
let error = new System.Text.StringBuilder()
p.OutputDataReceived.Add(fun args -> output.Append(args.Data) |> ignore)
p.ErrorDataReceived.Add(fun args -> error.Append(args.Data) |> ignore)
p.BeginErrorReadLine()
p.BeginOutputReadLine()
p.WaitForExit()
{ exitCode = p.ExitCode; stdout = output.ToString(); stderr = error.ToString() }
Вы также можете написать что-то вроде:
async {
while true do
let! args = Async.AwaitEvent p.OutputDataReceived
...
} |> Async.StartImmediate
дляОбработка реактивных событий в стиле F #.