Я звоню HttpClient
через Async.AwaitTask
, вызывая из агента (MailboxProcessor). Я хотел поймать ошибки во время HTTP-вызова, поэтому в рабочем процессе async использовался try...with
, но он полностью пропускает перехватывание исключений тайм-аута на стороне клиента, которые затем приводят к сбою агента.Улавливание тайм-аутов HttpClient в рабочем процессе async
Минимальное воспроизведение:
#r "System.Net.Http"
open System
open System.Net.Http
let client = new HttpClient()
client.Timeout <- TimeSpan.FromSeconds(1.)
async {
try
let! content = Async.AwaitTask <| client.GetStringAsync("http://fake-response.appspot.com/?sleep=30")
return content
with ex ->
// Does not catch client-side timeout exception
return "Caught it!"
}
|> Async.RunSynchronously
// Throws System.OperationCanceledException: The operation was canceled
я могу это исправить, сделав его полностью Синхронный, но предпочел бы сохранить весь стек асинхр, как может быть запущен много из них параллельно:
#r "System.Net.Http"
open System
open System.Net.Http
let client = new HttpClient()
client.Timeout <- TimeSpan.FromSeconds(1.)
try
Async.AwaitTask <| client.GetStringAsync("http://fake-response.appspot.com/?sleep=30")
|> Async.RunSynchronously
with ex ->
"Caught it!"
// Returns "Caught it!"
Есть ли эффективный способ ловли OperationCanceledException
в асинхронном контексте?
Это, кажется, что '' Async.Catch'' предназначен сделать, за исключением того, что он на самом деле не поймать исключение - поведение такое же, как пример OP. –