При вызове Async.RunSynchronously с тайм-аутом и CancellationToken значение тайм-аута, похоже, игнорируется. Я могу обойти это, вызвав CancelAfter для CancellationToken, но в идеале я хотел бы иметь возможность различать исключения, возникающие в рабочем процессе, TimeOutExceptions и OperationCanceledExceptions.
Я считаю, что приведенный ниже пример кода демонстрирует это.
open System
open System.Threading
let work =
async {
let endTime = DateTime.UtcNow.AddMilliseconds(100.0)
while DateTime.UtcNow < endTime do
do! Async.Sleep(10)
Console.WriteLine "working..."
raise ( Exception "worked for more than 100 millis" )
}
[<EntryPoint>]
let main argv =
try
Async.RunSynchronously(work, 50)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
let cts = new CancellationTokenSource()
try
Async.RunSynchronously(work, 50, cts.Token)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
cts.CancelAfter(80)
try
Async.RunSynchronously(work, 50, cts.Token)
with
| e -> Console.WriteLine (e.GetType().Name + ": " + e.Message)
Console.ReadKey(true) |> ignore
0
Выводит следующее, показывая, что тайм-аут эффективен только в первом случае (где CancelationToken не указан)
working...
working...
TimeoutException: The operation has timed out.
working...
working...
working...
working...
working...
working...
working...
Exception: worked for more than 100 millis
working...
working...
working...
working...
working...
working...
OperationCanceledException: The operation was canceled.
Это предполагаемое поведение? Есть ли способ получить поведение, которое мне нужно?
Спасибо!