3

I need to use System.Timers.Timer in an F# PCL library.

I'm currently targeting framework 4.5 and using Profile7 (I used the VS template) and it doesn't allow access to System.Timer.

According to this SO answer it's a known issue and is solved in 4.5.1.

I created a 4.5.1 C# PCL and checked its .csproj. It targets framework 4.6 and uses Profile32.

Is there a way to target the same in an F# project? I naively tried to update the .fsproj with the C# values, but it broke everything. :)

Thanks very much!

Community
  • 1
  • 1
Troy Kershaw
  • 590
  • 3
  • 8
  • Troy - Are you trying to use `System.Timers.Timer` (ie: https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx )? What are you needing to do with the timer? – Reed Copsey Mar 18 '15 at 23:29
  • Does it have to use a timer? You could use async or similar to work around it, which does work in PCL7... – Reed Copsey Mar 18 '15 at 23:39
  • No, I don't have to use a timer. Using async and recursion will work for me, but what other parts of the framework am I missing out on? :) – Troy Kershaw Mar 18 '15 at 23:43
  • 1
    The timer classes (both of them) are the big one I know of that were missing in the profiles, but should be there... – Reed Copsey Mar 18 '15 at 23:48

1 Answers1

5

The System.Timers.Timer (and System.Threading.Timer) classes don't work in the main F# PCL profiles. Given that normal F# async is supported, you can easily work around this by writing your own "timer" type. For example, the following (while a bit ugly) should mimic the Timer class functionality reasonably well:

type PclTimer(interval, callback) = 
    let mb = new MailboxProcessor<bool>(fun inbox ->
            async { 
                let stop = ref false
                while not !stop do
                    // Sleep for our interval time
                    do! Async.Sleep interval

                    // Timers raise on threadpool threads - mimic that behavior here
                    do! Async.SwitchToThreadPool()
                    callback()

                    // Check for our stop message
                    let! msg = inbox.TryReceive(1)
                    stop := defaultArg msg false
            })

    member __.Start() = mb.Start()
    member __.Stop() = mb.Post true
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373