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 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx. It spawns a background thread and fires an OnWork method at regular intervals. (Complete code is here [github] https://gist.github.com/1235595.)
在 F# 中是否有另一种可能更好或更惯用的方法来执行此操作?这可能是编写轮询后台工作类或其内置替代方案的更好方法。
EDIT
这是我根据乔尔的建议想到的。
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()
该服务使用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)
我希望有一种方法可以避免可变的情况CancellationTokenSource
, 可惜。
我可能想在异步工作流程中编写一个简单的循环。您可以使用do! Async.Sleep interval
在轮询之间睡眠 - 这有两个优点:你不会只是为了让它闲置而占用一个线程Thread.Sleep
,以及do!
如果您通过了考试,系统会自动为您检查是否取消CancellationToken
into Async.Start
.
另外,如果您的轮询操作涉及网络通信,那么您已经处于异步工作流程中,使得进行异步网络调用变得微不足道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)