1
\$\begingroup\$

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?

\$\endgroup\$
  • 1
    \$\begingroup\$ Is this real code from a real project? It's not clear what this code is really achieving (e.g. what is frameId, why is it always 1?), and I feel it's probably off-topic in its current form. The reason RemoveHandler isn't working is because you are creating a new handler each time. \$\endgroup\$ – VisualMelon Jul 26 at 21:22
  • 1
    \$\begingroup\$ Well, I have imported this to real time program, and add some more explanations. \$\endgroup\$ – Wojciech Szabowicz Jul 29 at 7:28
  • \$\begingroup\$ Thanks, much clearer the purpose now. However, your indentation is inconsistent and it looks like you never use the busResponseFactory binding, so I'm not sure this code can work. Has something gone missing? \$\endgroup\$ – VisualMelon Jul 29 at 12:35
  • \$\begingroup\$ I have updated the code, busResponseFactory is a part of bus subscription action \$\endgroup\$ – Wojciech Szabowicz Jul 31 at 7:12
  • \$\begingroup\$ There still seems to be something missing: there must be a case where 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 add None -> (* snip *) on the end. \$\endgroup\$ – VisualMelon Jul 31 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.