我正在尝试启动F#交互式子流程,通过标准输入向其发送代码,并通过标准输出接收响应。这是我的尝试代码(命令行args只是fsi
,它位于路径“):
let readStrStream (stream : StreamReader) =
let buffer = Array.create 1024 (char 0)
let bytesReceived = stream.Read(buffer, 0, 1024)
let chars = buffer |> Array.take bytesReceived
let str = String.Concat(chars)
str
let rec loop (proc : Process) = async {
proc.StandardInput.WriteLine("printf \"iteration\"")
let output = readStrStream proc.StandardOutput
printfn "%s" output
let error = readStrStream proc.StandardError
printfn "%s" error
return! loop proc }
let start proc =
Async.Start(loop proc, cancellationToken = cts.Token)
{ new IDisposable with member x.Dispose() = cts.Cancel }
[<EntryPoint>]
let main argv =
let procStart = new ProcessStartInfo(argv.[0], argv.[1..] |> String.concat " ")
procStart.UseShellExecute <- false
procStart.RedirectStandardInput <- true
procStart.RedirectStandardOutput <- true
procStart.RedirectStandardError <- true
procStart.WorkingDirectory <- "C:\\Users\\Philip"
let proc = Process.Start(procStart)
proc.StandardInput.AutoFlush <- true
let x = start proc
let y = Console.ReadLine()
0
此代码不起作用。当我运行它时,它只打印2个换行符。
如果我更改代码,
let proc = Process.Start(procStart)
Thread.Sleep(10000)
程序打印出来
Microsoft (R) F# Interactive version 14.0.23020.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
>
fsi
的启动文本。
我做了一些调试,这是我发现的。
在第一个代码中,第一次迭代时都调用readStrStream
返回\r\n
,第二次迭代时,它们首先调用挂起。
在第二个代码中,调用返回fsi
输出。
在我看来,由于某种原因,在拨打stream.Read
之后,流正在关闭。
我一直在玩fsi以外的其他东西,比如python或irb,但它们也没用。
我该如何解决这个问题?
答案 0 :(得分:1)
我想出了如何修复它,但我并不完全理解所发生的一切。 这个答案帮助我找到了解决方案。 Redirecting stdin and stdout in .Net
诀窍是使用proc.BeginOutputReadLine()
然后订阅proc.OutputDataReceived
而不是调用readline。我认为这个工作的原因与它是异步的有关。