gpt4 book ai didi

.net - 同步启动进程,输出 "streaming"

转载 作者:行者123 更新时间:2023-12-04 00:57:38 25 4
gpt4 key购买 nike

我正在考虑尝试从 F# 启动一个进程,等到它完成,但也逐渐读取它的输出。

这是正确/最好的方法吗? (就我而言,我正在尝试执行 git 命令,但这与问题无关)

let gitexecute (logger:string->unit) cmd = 
let procStartInfo = new ProcessStartInfo(@"C:\Program Files\Git\bin\git.exe", cmd)

// Redirect to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput <- true
procStartInfo.UseShellExecute <- false;

// Do not create the black window.
procStartInfo.CreateNoWindow <- true;

// Create a process, assign its ProcessStartInfo and start it
let proc = new Process();
proc.StartInfo <- procStartInfo;
proc.Start() |> ignore

// Get the output into a string
while not proc.StandardOutput.EndOfStream do
proc.StandardOutput.ReadLine() |> logger

我不明白的是 proc.Start() 如何可以返回一个 bool 值,并且还足够异步,以便我逐步获得输出。

不幸的是,我目前没有足够大的存储库 - 或足够慢的机器,无法判断事情发生的顺序......

更新

我尝试了布赖恩的建议,它确实有效。

我的问题有点含糊。我的误解是我认为 Process.Start() 返回了整个过程的成功,而不仅仅是“开始”,因此我看不出它是如何工作的。

最佳答案

您以您编写的形式编写的代码(几乎)没问题: process.Start 启动您在另一个进程中指定的进程,因此您的输出流读取将与您的进程执行并行发生。不过,一个问题是您应该在最后调用 process.WaitForExit - 输出流关闭的事实并不意味着该进程已终止。

但是,如果您尝试同时读取进程的 stdout 和 stderr,则会遇到同步读取问题:无法同步和同时读取 2 个流 - 如果读取 stdout 并且进程正在写入 stderr 并等待,则会死锁你消耗它的输出,反之亦然。

为了解决这个问题,您可以订阅 OutputDataRecieved 和 ErrorDataRecieved,如下所示:

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# 风格的响应式(Reactive)事件处理。

关于.net - 同步启动进程,输出 "streaming",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3065409/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com