Search code examples
timerf#

F# timers confusion: there seems to be several options, how to use it?


I have the following in C#:

var timer = new Timer(x => { task.Invoke(); }, state, startDelay, interval);

I'm trying to do the same in F# and from what I see online, there is a timer in System.Threading but there is also a timer in System.Timers and .. they're both called Timer.

This won't compile:

let timer = new Timer
                (
                    fun x -> (printfn "hello"),
                    new Object(),
                    1000,
                    5000
                )

I've established that the one in System.Threading is the one needed, but I don't understand what is wrong.

There error is:

Program.fs(21, 34): [FS0001] This expression was expected to have type 'unit' but here has type ''a * 'b * 'c * 'd'

The decompiler shows this:

public Timer(TimerCallback callback, [Nullable(2)] object state, int dueTime, int period)
  : this(callback, state, dueTime, period, true)
{
}

I don't understand the error at all. What am I doing wrong?


Solution

  • You're very close. The problem you're running into (and it's a common one) is that C# supports implicit conversion from the lambda (x => { task.Invoke(); }) into an instance of the TimerCallback delegate type. F# does not support implicit conversion as a rule. If you create an instance of the TimerCallback delegate yourself, you can see it all works fine:

    open System.Threading
    
    let timer = new Timer(
              TimerCallback (fun _ -> printfn "hello"),
              null,
              1000,
              5000
            )