Question
WojszaM on Thu, 15 Nov 2018 08:27:09
Hi, I have a question. I have a method that sends and receives messengers via serial port as a byte arrays,
to SerialPort DataRecived I am adding an event that will read response and assign it to type
so basically it should be easy and looks like this:
async { let buffer = Array.zeroCreate<byte> port.ReadBufferSize let response = new Response(buffer) let data_recived = async{ let! read_buffer = port.AsyncReadLineAsByte() response.Data <- read_buffer printfn "Response Buffer: %A response type: %A" read_buffer response.Data } |> Async.RunSynchronously port.DataReceived.Add(fun _-> data_recived) do! port.AsyncWriteLineAsByte messange //Something to wait for fired event return response.Data }
And type looks like
type Response(buffer: byte[]) = let mutable _response = buffer member this.Data with get() = _response and set(value) = _response <- value
Between sending messenge and returning byte array i need something that will wait for event to fire and finish so far i tried:
let! args = port.DataReceived |> Async.RunSynchronously
But this get stuck, also i tried:
while response.Data = buffer do printfn "Response: %A \r Buffer: %A" response.Data buffer
Well this works one time, if I send second message it goes to endless loop like this while is fire before event is fired.
Is there any way for this to work?
Replies
Mr. Tines on Thu, 15 Nov 2018 18:58:09
The way I would handle this is to communicate between the threads with a WaitHandle, like
use sync = new System.Threading.ManualResetEvent(false) // in a suitably long-lived scope
// otherwise `let sync = ...` and
// accept the leak ... async { let buffer = Array.zeroCreate<byte> port.ReadBufferSize let response = new Response(buffer) let data_received = async{ let! read_buffer = port.AsyncReadLineAsByte() response.Data <- read_buffer printfn "Response Buffer: %A response type: %A" read_buffer response.Data sync.Set() |> ignore } |> Async.RunSynchronously port.DataReceived.Add(fun _-> data_received) do! port.AsyncWriteLineAsByte messange sync.WaitOne() |> ignore sync.Reset() |> ignore return response.Data }