F # горячий, чтобы остановить Async.Start
Привет, у меня вопрос об асинхронности в F #.
Итак, у меня есть простая процедура, которая выполняется в фоновом режиме, помещается в член типа и выглядит так:
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повторным вызовом .