我是f#的新手,我对异步操作中的超时有疑问,这是使用串行com端口的简单通信,因此我有一种方法/功能:
let SendMessenge(port : Ports.SerialPort, messange: string) =
async {
do! port.AsyncWriteLine messange
let! response = port.AsyncReadLine() // this returns a string
return response
}
|> Async.RunSynchronously // the place i fiddled with
所有通信(信使)都在此模块中控制:
type SerialPort with
member this.AsyncWriteLine(messange : string) = this.BaseStream.AsyncWrite(this.Encoding.GetBytes(messange + "\n"))
member this.AsyncReadLine() =
async {
let messange_builder = StringBuilder()
let buffer_ref = ref (Array.zeroCreate<byte> this.ReadBufferSize)
let buffer = !buffer_ref
let last_char = ref 0uy
while !last_char <> byte '\n' do
let! readCount = this.BaseStream.AsyncRead buffer
last_char := buffer.[readCount-1]
messange_builder.Append (this.Encoding.GetString(buffer.[0 .. readCount-1])) |> ignore
messange_builder.Length <- messange_builder.Length-1
let response : string = messange_builder.ToString()
printfn "Response: %s" response
return response
}
基本上可以正常工作,它发送一条消息并接收响应,但是现在我想添加一个超时,以防我连接。我试图摆弄
|> Async.RunSynchronously(???, timeout, cancel_token)
但是没有运气。正如我在文档中看到的那样,它需要超时和取消令牌以及Async,就我而言,这个T0通用参数是什么?
答案 0 :(得分:4)
发生的情况是Async.RunSynchronously
是静态方法,而不是方法函数,因此它采用元组语法作为参数。因此,您不能部分应用它并将最后一个参数传递给它。
您可以这样做:
let response = async {
// ...
}
Async.RunSynchronously(response, timeout, cancel_token)
或者如果您真的要管道:
async {
// ...
}
|> fun response -> Async.RunSynchronously(response, timeout, cancel_token)