Reputation: 3
It is weird that extended property is not mutable... Could any one help?
open System.IO.Ports
open System.Text
open System.Text.RegularExpressions
type UAgent<'T> = MailboxProcessor<'T>
module ComPortManager =
type MailboxProcessor<'T> with
member this.sP = ref(new SerialPort("0"))
member this.receivedSeq : byte [] = Array.empty
member this.pastMsgSent : seq<string> = Seq.empty
type Cmd =
| Send = 0
| Remove = 1
| Add = 2
type UartOP =
| Open of unit
| Comm of Cmd * string
| Handler of Cmd * SerialDataReceivedEventHandler
let CreateComPort =
fun pN bR (p : System.IO.Ports.Parity) dB (sB : System.IO.Ports.StopBits) to' handler ->
match Array.exists (fun a -> a = pN) (SerialPort.GetPortNames()) with
| false -> failwith "Not valid comport!"
| _ -> ()
let mutable agent : UAgent<UartOP> =
UAgent.Start(handler)
let mutable sP = new SerialPort(pN)
agent.sP := sP
agent.sP.contents.Close()
match agent.sP.contents <> null with
| true ->
agent.sP.contents.Close()
| false ->
()
agent.sP.contents.BaudRate <- bR
printfn "\r\n=o==> %s" (bR.ToString())
printfn "\r\n=o==> %s" (sP.BaudRate.ToString())
printfn "\r\n=o==> %s" (agent.sP.contents.BaudRate.ToString())
agent.sP.contents.Parity <- p
agent.sP.contents.DataBits <- dB
agent.sP.contents.StopBits <- sB
agent.sP.contents.ReadTimeout <- to'
agent
The baud rate of property contents of variable sP doesn't change after trying to set it to bR...
The output looks like this:
=o==> 19200
=o==> 9600
=o==> 9600
Upvotes: 0
Views: 69
Reputation: 243041
The way you're trying to do this is not going to work. In F#, extensions cannot add new fields to existing types, and so you cannot really add additional mutable state.
What your definition is doing is that it is adding a bunch of read-only properties that are always returning a new value (a new reference cell in case of sP
or a new array in case of receivedSeq
). Every time you call agent.sP
, it creates a new value and returns it (so you end up mutating new copies that are immediately garbage collected).
To solve this, you'll need to create a new type that wraps a mailbox processor and adds the additional state, something along those lines:
type MyMailbox<'T>() =
let mbox = MailboxProcessor.Start( ... )
member val sP = ref(new SerialPort("0")) with get, set
member val receivedSeq : byte [] = Array.empty with get
Upvotes: 3