Возможно, у меня есть 2 вопроса вместо одного, но в любом случае.Совместное отмена в F # с отменой продолжения
Я осуществляю совместное аннулирование как here suggested. Вот мой тестовый код:
type Async with
static member Isolate(f : CancellationToken -> Async<'T>) : Async<'T> =
async {
let! ct = Async.CancellationToken
let isolatedTask = Async.StartAsTask(f ct)
return! Async.AwaitTask isolatedTask
}
let testLoop (ct: CancellationToken) = async {
let rec next ix =
if ct.IsCancellationRequested then()
else
printf "%i.." ix
Thread.Sleep 10
next (ix+1)
next 1
}
let cancellationSource = new CancellationTokenSource()
let onDone() = printfn "!! DONE"
let onError _ = printfn "!! ERROR"
let onCancel _ = printfn "!! CANCEL"
Async.StartWithContinuations (Async.Isolate testLoop, onDone, onError, onCancel, cancellationSource.Token)
Thread.Sleep(100)
cancellationSource.Cancel()
Thread.Sleep(500)
Как вы можете видеть, я начинаю асинхр с сделано, отменить и ошибки продолжений. Если я запустил этот код как есть, я получу следующий результат:
1..2..3..4..5..6..7..8 .. !! Совершено
Если я немного обновить метод Isolate
следующим образом:
static member Isolate(f : CancellationToken -> Async<'T>) : Async<'T> =
async {
let! ct = Async.CancellationToken
let isolatedTask = Async.StartAsTask(f ct)
let! x = Async.AwaitTask isolatedTask
x
}
я получить ожидаемый (сам) выход:
1..2..3..4 ..5..6..7 .. !! CANCEL
Почему у нас такая разница в поведении?
Возможно ли прервать testLoop
, если оно не отменено в течение некоторого таймаута?