gpt4 book ai didi

f# - 在异步工作流中捕获 HttpClient 超时

转载 作者:行者123 更新时间:2023-12-04 11:49:15 25 4
gpt4 key购买 nike

我打电话 HttpClient通过 Async.AwaitTask ,从代理(MailboxProcessor)内部调用。我想在 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在异步上下文中?

最佳答案

这是因为 HttpClient.GetStringAsync任务将被取消,而不是失败并返回 TimeoutException ,从而促使异步机制触发其无法处理的取消延续。解决此问题的简单方法如下:

async {
try
let! content =
client.GetStringAsync("http://fake-response.appspot.com/?sleep=30")
.ContinueWith(fun (t:Task<string>) -> t.Result)
|> Async.AwaitTask
return content
with ex ->
// Does not catch client-side timeout exception
return "Caught it!"
}

关于f# - 在异步工作流中捕获 HttpClient 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37112715/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com