运行简单的计时器

发布于 2024-11-28 19:19:11 字数 866 浏览 0 评论 0原文

我正在尝试在项目启动时运行简单的计时器:

type NJHomeViewModel(config : Config) as X  =  
    inherit ViewModelBase()

    do
        (X.Timer : Timer).Elapsed.Add(fun args -> X.OnTimedEvent(args))
        (X.Timer : Timer).Interval  <- 3000.0
        (X.Timer : Timer).Enabled   <- true
        (X.Timer : Timer).Start()

    member X.Timer = new Timer()

    member X.OnTimedEvent args = X.Change()

所以我希望每 3 秒运行一次 X.Change() 函数,它不会以这种方式工作,即使我将其添加到按钮也不会发生任何更改。

member X.Next =
    new RelayCommand((fun canExecute -> true),
        (fun action -> 
            (X.Timer : Timer).Elapsed.Add(fun args -> X.OnTimedEvent(args))
            (X.Timer : Timer).Interval  <- 3000.0
            (X.Timer : Timer).Enabled   <- true
            (X.Timer : Timer).Start() ))

通过“Tick”动作启动计时器的正确方法是什么?

I'm trying to run simple timer on project startup:

type NJHomeViewModel(config : Config) as X  =  
    inherit ViewModelBase()

    do
        (X.Timer : Timer).Elapsed.Add(fun args -> X.OnTimedEvent(args))
        (X.Timer : Timer).Interval  <- 3000.0
        (X.Timer : Timer).Enabled   <- true
        (X.Timer : Timer).Start()

    member X.Timer = new Timer()

    member X.OnTimedEvent args = X.Change()

So I want each 3 seconds run X.Change() function, it doesn't work this way, even when I added it to button nothing is changed.

member X.Next =
    new RelayCommand((fun canExecute -> true),
        (fun action -> 
            (X.Timer : Timer).Elapsed.Add(fun args -> X.OnTimedEvent(args))
            (X.Timer : Timer).Interval  <- 3000.0
            (X.Timer : Timer).Enabled   <- true
            (X.Timer : Timer).Start() ))

What is correct way to start my timer with a "Tick" action ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的旅程 2024-12-05 19:19:11

优先考虑使用异步循环而不是使用计时器;参见例如

http://lorgonblog.wordpress。 com/2010/03/27/f-async-on-the-client-side/

其中有一个示例

async {
    while true do
        do! Async.Sleep 1000
        textBox.Text <- System.DateTime.Now.ToString()
} |> Async.StartImmediate

Consider an async loop in preference to using a timer; see e.g.

http://lorgonblog.wordpress.com/2010/03/27/f-async-on-the-client-side/

which has an example like

async {
    while true do
        do! Async.Sleep 1000
        textBox.Text <- System.DateTime.Now.ToString()
} |> Async.StartImmediate
夜司空 2024-12-05 19:19:11

member X.Timer = new Timer() 这会创建一个带有 getter 的属性,并且每次创建新的 Timer 时都会访问此属性。

为了避免这种情况,您可以使用 let 绑定:

type NJHomeViewModel(config : Config) as X  =  
    inherit ViewModelBase()


    let timer = new Timer()
    do 
      timer.Elapsed.Add(fun args -> X.OnTimedEvent(args))
      timer.Interval  <- 3000.0
      timer.Enabled   <- true
      timer.Start()

    member X.Timer = timer

    member X.OnTimedEvent args = X.Change()

member X.Timer = new Timer() This creates a property with a getter and when you access this property every time a new Timer is created.

To avoid this you can use a let binding as:

type NJHomeViewModel(config : Config) as X  =  
    inherit ViewModelBase()


    let timer = new Timer()
    do 
      timer.Elapsed.Add(fun args -> X.OnTimedEvent(args))
      timer.Interval  <- 3000.0
      timer.Enabled   <- true
      timer.Start()

    member X.Timer = timer

    member X.OnTimedEvent args = X.Change()
当爱已成负担 2024-12-05 19:19:11

您正在使用基于服务器的 System.Timers.Timer ,它公开了已过去的事件。还有其他计时器可供您使用(例如系统。 Threading.Timer,您可以在其中提供回调方法或Windows.Forms.Timer,您可以在其中订阅 Tick 事件),因此您需要选择最适合您的应用程序和用例的一个。 MSDN 有一篇文章介绍了何时使用哪个 .NET 计时器此处

您正在使用的计时器,Elapsed 事件在某种状态下只会运行一次。所以这可能是你的问题。来自MSDN

如果 Enabled 设置为 true 并且 AutoReset 设置为 false,则计时器
仅引发一次 Elapsed 事件,即第一次间隔
过去了。

线程计时器看起来像

new Timer((fun _ -> YourMethod), null, 1000, 1000)

Windows.Forms.Timer 看起来像

formsTimer.Tick.Add( fun _ -> YourMethod())

在 WPF 中,您还有 DispatcherTimer 可供您使用(更多此处)。在 F# 中,这看起来像

let tmr = new DispatcherTimer(Interval = TimeSpan.FromSeconds(1.0))
tmr.Tick.Add( fun _ -> YourMethod())
tmr.Start()

另一个问题中对 Forms.Timer 和 DispatcherTimer 进行了简明比较< /a> 这可能会帮助您为您的应用程序选择合适的。

You are using the server-based System.Timers.Timer which exposes an Elapsed event. There are other Timers available to you (e.g. the System.Threading.Timer where you can provide a callback method or the Windows.Forms.Timer where you can subscribe to the Tick event) so you need to pick the one most appropriate for your application and your use case. MSDN has an article about when to use which .NET Timer here

For the timer you are using, the Elapsed event will only run once if in a certain state. So that could be your problem. From MSDN

If Enabled is set to true and AutoReset is set to false, the Timer
raises the Elapsed event only once, the first time the interval
elapses.

The Threading timer would look something like

new Timer((fun _ -> YourMethod), null, 1000, 1000)

The Windows.Forms.Timer would look something like

formsTimer.Tick.Add( fun _ -> YourMethod())

In WPF you also have the DispatcherTimer available to you (more here). in F# this would look something like

let tmr = new DispatcherTimer(Interval = TimeSpan.FromSeconds(1.0))
tmr.Tick.Add( fun _ -> YourMethod())
tmr.Start()

There is a concise comparison of Forms.Timer and DispatcherTimer in another question on SO that might help you choose the right one for your app.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文