F#hot to stop Async.Start
こんにちは私はF#の非同期について質問があります。
だから私はタイプのメンバーに配置された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から戻ることもできます。StartObservable
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ます。