Я читаю F# для удовольствия и пользы — Асинхронное программирование. В разделе Отмена рабочих процессов есть следующий пример:
let testLoop = async {
for i in [1..100] do
// do something
printf "%i before.." i
// sleep a bit
do! Async.Sleep 10
printfn "..after"
}
open System
open System.Threading
// create a cancellation source
let cancellationSource = new CancellationTokenSource()
// start the task, but this time pass in a cancellation token
Async.Start (testLoop,cancellationSource.Token)
// wait a bit
Thread.Sleep(200)
// cancel after 200ms
cancellationSource.Cancel()
Об этом говорят:
В F# любой вложенный асинхронный вызов будет автоматически проверять токен отмены!
В данном случае это была строка:
do! Async.Sleep(10)
Как видно из вывода, именно в этой строке произошла отмена.
Однако для меня (VS2010, F # 2.0, F # Interactive) я получаю следующий результат. Обратите внимание, как он также печатает ..after
после того, как я отменил токен. Они просто неверны?
1 before....after
2 before....after
3 before....after
4 before....after
5 before....after
6 before....after
7 before....after
8 before....after
9 before....after
10 before....after
11 before....after
12 before....after
13 before..
val cancellationSource : CancellationTokenSource
>
..after
Так что, возможно, проверка на отмену выполняется при вводе Async.Sleep
? Нет, тогда было бы напечатано:
13 before....after
14 before..
val cancellationSource : CancellationTokenSource
>
Так что похоже, что проверка на самом деле находится в цикле for! т.е. он продолжает работать до тех пор, пока цикл for не будет отменен. Вот как это работает? Что тогда, если я предпочитаю, чтобы он проверял после сна?
Этот вопрос, кажется, намекает на то, что отмена работает так, как я описал выше: Я явно проверяю отмену/прекращение асинхронных вычислений?
Редактировать: Что касается того, что это только в FSI 2.0: что происходит со следующим циклом, если один спит 200 мс, 2500 мс и 4000 мс соответственно? Он печатает середину?
let testLoop = async {
for i in [1..5] do
printf "%i before.." i
do! Async.Sleep 2000
printfn "..middle.."
do! Async.Sleep 1000
printfn "..after"
}
..middle..
, а Fsi v11 и v12 - нет. - person Leaf Garland   schedule 17.01.2014