f# - F# propper 删除 ElapsedEventHandler 处理程序
问题描述
嗨,我有一个问题,我有一个快速程序,它会在每 10 秒内执行一次操作,它看起来很简单:
[<EntryPoint>]
let main argv =
let timer = new Timer(float 10000)
let OnTimedEvent (frameId:uint32) : ElapsedEventHandler = new ElapsedEventHandler (fun obj args -> printfn "DATE: %A FRAME: %i" DateTime.Now frameId)
while(true) do
let keyStroke = Console.ReadKey()
if keyStroke.Key.Equals(ConsoleKey.Enter) then
let frameId = 1u
timer.AutoReset <- true
timer.Elapsed.RemoveHandler(OnTimedEvent frameId)
timer.Elapsed.AddHandler(OnTimedEvent frameId)
timer.Start();
else
printfn "%c pressed" keyStroke.KeyChar
0
问题是我无法按原样正确删除处理程序,如果我在启动后按 Enter 并每 10 秒给我一条消息,那么这就是我的目标。但是,如果我按 Enter 3 次,它会增加并给我 3 个消息,依此类推,但我只想要一个。
另一件事是,如果我从中删除参数,它会完美运行,所以我认为问题出在参数上。有什么解决方案吗?
解决方案
您当前实现的问题是每次调用都会OnTimedEvent
返回ElapsedEventHandler
. 当您按如下方式调用它时:
timer.Elapsed.RemoveHandler(OnTimedEvent frameId)
您正在删除以前未注册的新处理程序,因此实际上没有任何反应。当您更改代码以添加/删除相同的处理程序时,您始终使用相同的实例:
let frameId = 1u
let timedHandler = new ElapsedEventHandler (fun obj args ->
printfn "DATE: %A FRAME: %i" DateTime.Now frameId)
timer.Elapsed.RemoveHandler(timedHandler)
timer.Elapsed.AddHandler(timedHandler)
现在您没有一种将 传递frameId
给您的事件处理程序的好方法。在您的代码中,frameId
总是1u
如此,因此很难看到您真正想要什么,但您可以使其可变:
let mutable frameId = 1u
let timedHandler = new ElapsedEventHandler (fun obj args ->
printfn "DATE: %A FRAME: %i" DateTime.Now frameId)
frameId <- 2u
timer.Elapsed.RemoveHandler(timedHandler)
timer.Elapsed.AddHandler(timedHandler)
也就是说,目前还不清楚你想要做什么,也许有一种完全不同的方式来做你想做的事。
一种完全不同的方法是使用MailboxProcessor
保持当前frameId
并处理两种类型的消息 - 一种由计时器每 10 秒触发一次,另一种可用于更改帧 ID:
type Message =
| Tick
| ChangeFrameId of uint32
let agent = MailboxProcessor.Start(fun inbox ->
let rec run frameId = async {
let! msg = inbox.Receive()
match msg with
| ChangeFrameId newId ->
return! run newId
| Tick ->
printfn "DATE: %A FRAME: %i" DateTime.Now frameId
return! run frameId }
run 1u)
let timer = new Timer(float 10000, AutoReset = true)
timer.Elapsed.Add(fun _ -> agent.Post(Tick))
timer.Start()
agent.Post(ChangeFrameId 2u)
推荐阅读
- java - 使用 Prim 和堆计算 MST 的总重量
- laravel - 如何从 laravel 中具有父 ID 的集合创建嵌套数组?
- c++ - UI 自动化示例错误:LNK2001 无法解析的外部符号 _CLSID_AccPropServices
- c# - 为什么 Visual Studio 在 Razor (.cshtml/.razor) 中突出显示双花括号?
- javascript - 当图像大小不同时,如何在 carasoul 中制作响应式图像?
- javascript - 来自javascript的二维码阅读器
- java - 将对象投射到 ? 类型作为 List 的参数
- python - pytest-bdd 是否支持标记示例并通过 pytest -k tag_name 使用标记调用测试
- angular - 错误:fakeAsync() 测试助手需要 zone-testing.js,但找不到。使用 serenityJS+Jasmine 在 Angular webapp 上运行测试时
- c# - Azure IoT 中心版本 1.37 CreateFromConnectionString NotImplementedException