【发布时间】:2015-12-27 22:12:42
【问题描述】:
我正在尝试启动一个 F# 交互式子进程,通过标准输入向它发送代码,并通过标准输出接收响应。这是我尝试的代码(命令行参数只是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,但它们也不起作用。
我该如何解决这个问题?
【问题讨论】:
-
从内存中旧版本(可能还有新版本)使用奇怪的事件循环来读取可能绕过标准输入的输入。你到底想在这里做什么?
-
@JohnPalmer 在此代码中,我试图一遍又一遍地发送一行代码。我最终试图做出一种概括的repl。
-
@JohnPalmer 不完全是。我所说的广义 repl 的意思是这个程序可以用作 python 或 ruby(或其他任何东西)repl 接口。它基本上是多个后端的前端。您提到的项目甚至建议在某些情况下使用标准输入和标准输出 - fsharp.github.io/FSharp.Compiler.Service/interactive.html。