问题
I usually write Windows services in C# but I'm giving it a go in F#. For a polling serivce, like this one, I ordinarily use a class I've written, which is similar to BackgroundWorker. It spawns a background thread and fires an OnWork method at regular intervals. (Complete code is here [github].)
Is there another, perhaps better or more idiomatic, way to do this in F#? It could be a better way to write the polling background worker class, or built-in alternatives to it.
EDIT
Here's what I came up, based on Joel's suggestion.
module Async =
open System.Diagnostics
let poll interval work =
let sw = Stopwatch()
let rec loop() =
async {
sw.Restart()
work()
sw.Stop()
let elapsed = int sw.ElapsedMilliseconds
if elapsed < interval then
do! Async.Sleep(interval - elapsed)
return! loop()
}
loop()
//Example
open System.Threading
let cts = new CancellationTokenSource()
Async.Start(Async.poll 2000 (fun () -> printfn "%A" DateTime.Now), cts.Token)
Thread.Sleep(TimeSpan.FromSeconds(10.0))
cts.Cancel()
The service using poll
:
type MyService() =
inherit System.ServiceProcess.ServiceBase()
let mutable cts = new CancellationTokenSource()
let interval = 2000
override __.OnStart(_) =
let polling = Async.poll interval (fun () ->
//do work
)
Async.Start(polling, cts.Token)
override __.OnStop() =
cts.Cancel()
cts.Dispose()
cts <- new CancellationTokenSource()
override __.Dispose(disposing) =
if disposing then cts.Dispose()
base.Dispose(true)
I wish there was a way to avoid the mutable CancellationTokenSource
, but alas.
回答1:
I might be tempted to write a simple loop in an asynchronous workflow. You can use do! Async.Sleep interval
to sleep in between polling - this has two advantages: you're not tying up a thread just to have it sit idle with Thread.Sleep
, and the do!
automatically checks for cancellation for you if you pass a CancellationToken
into Async.Start
.
Plus, if your polling operation involves network communication, you're already in an async workflow, making it trivial to make async network calls.
来源:https://stackoverflow.com/questions/7519755/writing-a-polling-windows-service