.NET读取Git分支时,先等待进程退出为何会卡住?
问题描述
我尝试通过.NET读取Git仓库的分支列表,以下脚本可以正常运行:
open System.Diagnostics [<RequireQualifiedAccess>] module Async = let parallel2 a b = async { let! x = Async.StartChild a let! y = Async.StartChild b let! i = x let! j = y return i, j } async { let fileName = "git" let args = [ "-P"; "branch"; "-a" ] let psi = ProcessStartInfo( FileName = fileName, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true ) for arg in args do psi.ArgumentList.Add(arg) let p = Process.Start(psi, EnableRaisingEvents = true) let! ct = Async.CancellationToken let! output, () = Async.parallel2 ( p.StandardOutput.ReadToEndAsync() |> Async.AwaitTask ) ( p.WaitForExitAsync(ct) |> Async.AwaitTask ) if p.ExitCode <> 0 then let! error = p.StandardError.ReadToEndAsync() |> Async.AwaitTask return failwith $"{error}" else return output } |> Async.RunSynchronously |> printfn "%s"
但以下脚本始终无法终止,卡在WaitForExitAsync处:
open System.Diagnostics async { let fileName = "git" let args = [ "-P"; "branch"; "-a" ] let psi = ProcessStartInfo( FileName = fileName, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true ) for arg in args do psi.ArgumentList.Add(arg) let p = Process.Start(psi, EnableRaisingEvents = true) let! ct = Async.CancellationToken do! p.WaitForExitAsync(ct) |> Async.AwaitTask if p.ExitCode <> 0 then let! error = p.StandardError.ReadToEndAsync() |> Async.AwaitTask return failwith $"{error}" else let! output = p.StandardOutput.ReadToEndAsync() |> Async.AwaitTask return output } |> Async.RunSynchronously |> printfn "%s"
补充说明:运行环境为Ubuntu上的.NET 6。
原因解释
这是因为标准输出缓冲区已满导致的进程阻塞:
- 当重定向子进程的标准输出/错误流时,子进程会将输出写入对应缓冲区。如果父进程未及时读取这些缓冲区,一旦缓冲区被填满,子进程会暂停执行,等待父进程读取数据腾出空间。
- 第二个脚本先调用
WaitForExitAsync等待子进程结束,但此时父进程并未读取StandardOutput的内容。Git命令输出的分支信息会填满标准输出缓冲区,导致Git进程卡住无法退出,进而让WaitForExitAsync永远无法完成。 - 第一个脚本通过
parallel2同时启动读取标准输出和等待进程退出的异步任务,进程输出内容时父进程能及时读取缓冲区,不会让子进程因缓冲区满而阻塞,因此可以正常结束。
另外需要注意:如果Git命令同时有大量错误输出,仅读取标准输出也可能导致类似问题,最佳实践是同时异步读取标准输出和标准错误流,避免任一缓冲区满导致进程阻塞。
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

