F # hot per interrompere Async.Start
Salve, ho una domanda sull'asincronizzazione in F #.
Quindi ho una semplice procedura che viene eseguita in background che viene inserita in un membro di un tipo e assomiglia a:
type Sender () =
member this.Start udpConectionPool =
async { (* ome operation that continusly send something to throu udp*) } |> Async.Start
Quindi questo inizia e inizia a inviare continuamente frame su UDP senza bloccare il resto del programma, ma di tanto in tanto voglio riavviare il thread (diciamo che voglio aggiungere un nuovo endpoint che lo invierebbe a quello è il parametro udpConectionPool).
Stavo pensando a qualcosa come scaricare l'attività nel membro e poi:
member this.Stop = async { do! (*stop async start member that contains task*)}
E poi posso riavviare questa attività con un pool di connessioni aggiornato, ma non so se posso farlo. La mia domanda è: è possibile interrompere tale compito o, in caso contrario, esiste un modo migliore per farlo?
Risposte
Il modo standard per annullare i flussi di lavoro asincroni F # consiste nell'usare un file CancellationToken. Quando chiami Async.Start, puoi fornire un token di cancellazione. Quando il token viene annullato, il flusso di lavoro asincrono si interromperà (al termine del lavoro di blocco corrente):
open System.Threading
let cts = new CancellationTokenSource()
let work = async { (* ... *) }
Async.Start(work, cts.Token)
cts.Cancel() // Sometime later from another thread
Per integrarlo con Sender, puoi memorizzare la corrente CancellationTokenSourcee avere un Stopmetodo che la cancella (se vuoi mantenerla all'interno di una classe stateful). In alternativa, puoi tornare IDisposabledal Startmetodo in un modo simile a come funziona l' Observableinterfaccia:
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() }
In questo modo, il chiamante Startè responsabile della memorizzazione del reso IDisposablee dello smaltimento prima di chiamare di Startnuovo.