问题描述
因此,我有一个简单的过程,该过程在backgrount中运行,并放置在类型的成员中,如下所示:
type Sender () =
member this.Start udpConectionPool =
async { (* ome operation that continusly send something to throu udP*) } |> Async.Start
因此,它开始并开始通过UDP连续发送帧,而不会阻塞程序的其余部分,但是我有时会想重新启动线程(让我们说我想添加新的端点,它将把它发送到udpConectionPool参数)。
我正在考虑将任务转储给成员,然后:
member this.Stop = async { do! (*stop async start member that contains task*)}
然后,我可以使用更新的连接池重新启动此任务,但是我不知道是否可以这样做。 我的问题是,是否可以停止此类任务,或者如果没有更好的方法呢?
解决方法
取消F#异步工作流的标准方法是使用CancellationToken
。致电Async.Start
时,您可以提供取消令牌。当令牌被取消后,异步工作流程将停止(在当前阻止工作完成之后):
open System.Threading
let cts = new CancellationTokenSource()
let work = async { (* ... *) }
Async.Start(work,cts.Token)
cts.Cancel() // Sometime later from another thread
要将其与Sender
集成,您可以存储当前的CancellationTokenSource
并使用Stop
方法来取消它(如果您想将其保留在有状态的类中)。或者,您可以通过IDisposable
接口的工作方式,从Start
方法返回Observable
:
type Sender () =
member this.Start udpConectionPool =
let cts = new CancellationTokenSource()
let work = async { (* ... *) }
Async.Start(work,cts.Token)
{ new System.IDisposable with
member x.Dispose() = cts.Cancel() }
通过这种方式,Start
的调用方负责存储返回的IDisposable
,并在再次调用Start
之前将其处置。