【发布时间】:2016-05-09 09:55:07
【问题描述】:
我通过Async.AwaitTask 呼叫HttpClient,是从代理(邮箱处理器)内部调用的。我想在 HTTP 调用期间捕获错误,因此在异步工作流程中使用了 try...with,但它完全错过了捕获客户端超时异常,然后导致代理崩溃。
最小复制:
#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 的示例相同。
标签: f# dotnet-httpclient f#-async