将接收到的串行数据事件处理程序添加到f#串行端口读取器

将接收到的串行数据事件处理程序添加到f#串行端口读取器,f#,F#,我在f#中有简单的读写指令,用于在串行端口之间进行通信: async { do! port.AsyncWriteLineAsByte messange let! response = port.AsyncReadLineAsByte() return response } 其中响应为字节[],方法简单如下: member this.AsyncReadLin

我在f#中有简单的读写指令,用于在串行端口之间进行通信:

        async {
            do! port.AsyncWriteLineAsByte messange            
            let! response = port.AsyncReadLineAsByte() 

            return response
        }
其中响应为字节[],方法简单如下:

    member this.AsyncReadLineAsByte() : Async<byte[]> =
        async { 

            let buffer_ref = ref (Array.zeroCreate<byte> this.ReadBufferSize)
            let buffer = !buffer_ref

            let! read_bytes = this.BaseStream.AsyncRead(buffer, 0, this.ReadBufferSize)

            return buffer
        }
但是没有运气,文档更重要的是,对于f#,它只是指定原型和方法构造,而不是实际用途。我需要一个事件和一种返回该值的方法,有方法吗

编辑:

我已经能够添加事件,因为串行端口名称空间具有DataReceived.AddHandler事件订阅

现在看来:

        async {

        let data_recived() =
            async{
                let! buffer = port.AsyncReadLineAsByte()
                printfn "Response from event %A" buffer
                // return buffer
            } |> fun response -> Async.RunSynchronously(response)

        port.DataReceived.AddHandler(fun _ _ -> data_recived())

        do! port.AsyncWriteLineAsByte messange  
        let! response = port.AsyncReadLineAsByte()            

        return response
    }
它是有效的,问题仍然是如何从事件中返回这样的值,如果我执行以下操作:

    async {

        let data_recived_event = port.AsyncReadLineAsByte() 

        do! port.AsyncWriteLineAsByte messange  

        port.DataReceived.AddHandler(data_recived_event) //  it says SerialDataReciveHandler is what he expects

        let! response = ??? 

        return response
    }
            let data_recived() =
                async{
                    let! buffer = port.AsyncReadLineAsByte()

                    printfn "Response from event %A" buffer
                    return buffer
                } |> fun response -> Async.RunSynchronously(response)

            port.DataReceived.AddHandler(fun _ _ -> response = data_recived())

Is说它需要uint和get bool

我不是串行端口工作原理的专家,但您可以使用
async.waitevent
操作在
async
工作流中等待事件。你可以这样写:

let writeAndRead () = async {
  let port = new SerialPort("COM1")
  port.Write("TEST")
  let mutable finished = false
  while not finished do
    let! e = port.DataReceived |> Async.AwaitEvent
    let data = port.ReadExisting()
    printfn "GOT: %A" data
    finished <- data.Contains("EOF") }

编辑:在将任何数据写入端口之前移动了
队列
事件处理程序设置。

!e=queue.AsyncGet()并让!e=port.DataReceived |>Async.AwaitEvent被卡住并等待,即使事件是received@WojciechSzabowicz我进行了编辑,将
datareceived
处理程序设置移到写入端口的行之前。这可能是错过某项活动的原因。有了这些变化,我认为所有的事件都应该被正确地记录下来,而且没有一个会丢失。
let writeAndRead () = async {
  let queue = BlockingQueueAgent<_>(Int32.MaxValue)
  let port = new SerialPort("COM1")
  port.DataReceived.Add(fun e -> queue.Add(e))
  port.Write("TEST")
  let mutable finished = false
  while not finished do
    let! e = queue.AsyncGet()
    let data = port.ReadExisting()
    finished <- data.Contains("EOF") }