Writing a polling Windows service

我是研究僧i 提交于 2019-12-12 08:38:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!