Я использую Async.Catch для обработки исключений, создаваемых асинхронными рабочими процессами:
work
|> Async.Catch
|> Async.RunSynchronously
|> fun x -> match x with
| Choice1Of2 _ -> () // success
| Choice2Of2 ex -> // failure, handle exception
Сегодня я заметил, что OperationCanceledExceptions не обрабатываются Async.Catch. Вместо того, чтобы получить выбор от Async.Catch, исключение продолжает всплывать, пока не доходит до меня. Я ожидал, что следующий тест будет красным, но он зеленый:
[<Test>]
let ``Async.Catch doesnt work on OperationCancelledExceptions``() =
use cancellationTokenSource = new System.Threading.CancellationTokenSource(1000)
let work = async {
while true do
do! Async.Sleep 100
}
(fun () -> work
|> Async.Catch
|> fun x -> Async.RunSynchronously (x, cancellationToken=cancellationTokenSource.Token)
|> ignore)
|> should throw typeof<System.OperationCanceledException>
Оценка некоторых исключений с помощью Async.Catch + Choices + сопоставление и некоторых других с использованием блоков try/catch не кажется правильной... это будет выглядеть следующим образом, что слишком сложно. Кроме того, мне интересно, какая польза от Async.Catch, так как я все равно должен использовать блок try/catch...:
[<Test>]
let ``evaluating exceptions of async workflows``() =
use cancellationTokenSource = new System.Threading.CancellationTokenSource(1000)
let work = async {
while true do
do! Async.Sleep 100
}
try
work
|> Async.Catch
|> fun x -> Async.RunSynchronously (x, cancellationToken=cancellationTokenSource.Token)
|> fun x -> match x with
| Choice1Of2 result -> () // success, process result
| Choice2Of2 ex -> () // failure, handle exception
with ex -> () // another failure, handle exception here too
Как лучше всего обрабатывать исключения асинхронных рабочих процессов? Должен ли я просто сбросить Async.Catch и везде использовать блоки try/catch?