Запустите простой таймер - PullRequest
       13

Запустите простой таймер

1 голос
/ 11 августа 2011

Я пытаюсь запустить простой таймер при запуске проекта:

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"?

Ответы [ 3 ]

3 голосов
/ 11 августа 2011

Рассмотрим асинхронный цикл вместо использования таймера;см., например,

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
2 голосов
/ 11 августа 2011

member X.Timer = new 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()
1 голос
/ 11 августа 2011

Вы используете серверный System.Timers.Timer , который предоставляет событие Elapsed. Вам доступны другие таймеры (например, System.Threading.Timer , где вы можете указать метод обратного вызова или Windows.Forms.Timer , где вы можете подписаться на событие Tick). поэтому вам нужно выбрать наиболее подходящий для вашего приложения и вашего варианта использования. В MSDN есть статья о том, когда использовать .NET Timer здесь

Для таймера, который вы используете, событие Elapsed будет запускаться только один раз, если оно находится в определенном состоянии. Так что это может быть вашей проблемой. От MSDN

Если для параметра «Разрешено» установлено значение «истина», а для параметра «Автосброс» установлено значение «ложь», таймер вызывает событие 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 в другом вопросе по SO , который может помочь вам выбрать правильный для вашего приложения.

...