I have a simple method that receives messages from bus, builds response and send it back, and it looks like:
let readFromBusAndSendRequest =
let mutable timer = new Timer(float 10000)
let OnTimedEvent (frameId:uint32, projectId:uint32, cabinId:byte) (bus:IBus) : ElapsedEventHandler =
new ElapsedEventHandler (fun _ _ ->
printfn "Publishing UM1 Request %A Frame %A" DateTime.Now framId
//Create request
bus.Publish<RequestMessage>(request, HubSubscriptionId))
match this.Bus with
| Some bus ->
let cabinetSubscribeId = sprintf "Project.%i.Cabin.%i" this.ProjectId this.CabinId
let busResponseFactory (response : BasicMessage) =
match response.FrameType with
| FrameType.SERVICE_LIST ->
let serviceListResponse : ServiceListMessage = response :?> ServiceListMessage
let isMessageValid = serviceListResponse.FrameWithoutCrc.IsValidCrc32(serviceListResponse.ResponseCrc32)
match isMessageValid with
| true ->
publishAck bus (serviceListResponse, RequestedService.Unknown)
timer.Dispose()
timer <- new Timer(float 10000, AutoReset = true)
timer.AutoReset <- true
timer.Elapsed.AddHandler(OnTimedEvent ((serviceListResponse.FrameId + 1u), this.ProjectId, byte this.CabinId) bus)
timer.Start();
| false -> publishNack bus (serviceListResponse, RequestedService.Unknown) NackRejectionReason.InvalidCrc
| false -> publishNack bus (serviceResponse, serviceResponse.RequestedService) NackRejectionReason.InvalidCrc
| _ -> printfn "OTHER SUPPORT"
let handler = Action<ResponseMessage>(fun response ->
printfn "Response %A frame type %s response id %i" response.ProjectId (response.FrameType.ToString()) response.FrameId;
busResponseFactory response |> ignore)
bus.Subscribe<ResponseMessage>(cabinetSubscribeId, handler, Action<FluentConfiguration.ISubscriptionConfiguration>(fun sub -> sub.WithTopic(cabinetSubscribeId) |> ignore)) |> ignore
When I get a certain type of response(in this case SERVICE_LIST), I want it to attach an event to the Timer, and make it run each 10 seconds. All parameters needed are from message received from bus
As you see, I used a mutable
timer because each time I press I receive new SERVICE_LIST message, an event is added but but not removed, and believe me I tried:
timer.Elapsed.RemoveHandler(OnTimedEvent frameId)
Probably because frame id is different every time.
Instead of dispose, but it did not work; new events were just added but not removed. So is there a better way to conquer this mess?
I know it is because I create new event each time, but how to remove old one?
frameId
, why is it always1
?), and I feel it's probably off-topic in its current form. The reasonRemoveHandler
isn't working is because you are creating a new handler each time. \$\endgroup\$busResponseFactory
binding, so I'm not sure this code can work. Has something gone missing? \$\endgroup\$busResponseFactory
is a part of bus subscription action \$\endgroup\$this.Bus = None
or similar. It's best to provide as much context as you can, but if it really isn't important (i.e. doesn't interact with the other code at all) then it should be ok to just addNone -> (* snip *)
on the end. \$\endgroup\$