开发者

F# Start/Stop class instance at the same time

开发者 https://www.devze.com 2023-02-16 09:12 出处:网络
I am doing F# programming, I have some special requirements. I have 3 class instances; each class instance has to run for one hour every day, from 9:00AM to 10:00AM.I want to control them from main pr

I am doing F# programming, I have some special requirements. I have 3 class instances; each class instance has to run for one hour every day, from 9:00AM to 10:00AM. I want to control them from main program, starting them at the same time, and stop them also at the same time. The following is my code to start them at the same time, but I don’t know how to stop them at the same time.

#light
module Program
open ClassA
open ClassB
open ClassC

let A = new CalssA.A("A")
let B = new ClassB.B("B")
let C = new ClassC.C("C")

let task = [ async { return A.jobA("A")};
             async { return B.jobB("B")};
             async { return C.jobC("C")} ]
task |> Async.Parallel |> Async.RunSynchronously |> ignore

Anyone knows hows to stop all 3 class instances at 10:00AM, please show me your code.

Someon开发者_C百科e told me that I can use async with cancellation tokens, but since I am calling instance of classes in different modules, it is difficult for me to find suitable code samples. Thanks,


The jobs themselves need to be stoppable, either by having a Stop() API of some sort, or cooperatively being cancellable via CancellationTokens or whatnot, unless you're just talking about some job that spins in a loop and you'll just thread-abort it eventually? Need more info about what "stop" means in this context.


As Brian said, the jobs themselves need to support cancellation. The programming model for cancellation that works the best with F# is based on CancellationToken, because F# keeps CancellationToken automatically in asynchronous workflows.

To implement the cancellation, your JobA methods will need to take additional argument:

type A() = 
  member x.Foo(str, cancellationToken:CancellationToken) =
    for i in 0 .. 10 do 
      cancellationToken.ThrowIfCancellationRequested() 
      someOtherWork()

The idea is that you call ThrowIfCancellationRequested frequently during the execution of your job. If a cancellation is requested, the method thorws and the operation will stop. Once you do this, you can write asynchronous workflow that gets the current CancellationToken and passes it to JobA member when calling it:

let task = 
  [ async { let! tok = Async.CancellationToken
            return A.JobA("A", tok) };
    async { let! tok = Async.CancellationToken
            return B.JobB("B") }; ]

Now you can create a new token using CancellationTokenSource and start the workflow. When you then cancel the token source, it will automatically stop any jobs running as part of the workflow:

let src = new CancellationTokenSource()
Async.Start(task, cancellationToken = src.Token)

// To cancel the job:
src.Cancel()


You asked this question on hubfs.net, and I'll repeat here my answer: try using Quartz.NET. You'd just implement IInteruptableJob in A,B,C, defining how they stop. Then another job at 10:00AM to stop the others.

Quartz.NET has a nice tutorial, FAQ, and lots of examples. It's pretty easy to use for simple cases like this, yet very powerful if you ever need more complex scheduling, monitoring jobs, logging, etc.

0

精彩评论

暂无评论...
验证码 换一张
取 消