gpt4 book ai didi

F# 在 Async.Catch 上继续

转载 作者:行者123 更新时间:2023-12-05 02:20:33 26 4
gpt4 key购买 nike

我正在执行许多异步 Web 请求并使用 Async.Parallel。像这样的东西:

xs                          
|> Seq.map (fun u -> downloadAsync u.Url)
|> Async.Parallel
|> Async.Catch

一些请求可能会抛出异常,我想记录它们并继续处理其余的 url。我找到了 Async.Catch函数,但这会在抛出第一个异常时停止计算。我知道我可以在异步表达式中使用 try...with 表达式来计算整个列表,但是,我认为,这意味着将日志函数传递给我的 downloadAsync 函数改变了他的类型。有没有其他方法可以捕获异常,记录它们并继续使用其余的网址?

最佳答案

“技巧”是将 catch 移动到 map 中,这样 catch 也可以并行化:

open System
open System.IO
open System.Net

type T = { Url : string }

let xs = [
{ Url = "http://microsoft.com" }
{ Url = "thisDoesNotExists" } // throws when constructing Uri, before downloading
{ Url = "https://thisDotNotExist.Either" }
{ Url = "http://google.com" }
]

let isAllowedInFileName c =
not <| Seq.contains c (Path.GetInvalidFileNameChars())

let downloadAsync url =
async {
use client = new WebClient()
let fn =
[|
__SOURCE_DIRECTORY__
url |> Seq.filter isAllowedInFileName |> String.Concat
|]
|> Path.Combine
printfn "Downloading %s to %s" url fn
return! client.AsyncDownloadFile(Uri(url), fn)
}

xs
|> Seq.map (fun u -> downloadAsync u.Url |> Async.Catch)
|> Async.Parallel
|> Async.RunSynchronously
|> Seq.iter (function
| Choice1Of2 () -> printfn "Succeeded"
| Choice2Of2 exn -> printfn "Failed with %s" exn.Message)

(*
Downloading http://microsoft.com to httpmicrosoft.com
Downloading thisDoesNotExists to thisDoesNotExists
Downloading http://google.com to httpgoogle.com
Downloading https://thisDotNotExist.Either to httpsthisDotNotExist.Either
Succeeded
Failed with Invalid URI: The format of the URI could not be determined.
Failed with The remote name could not be resolved: 'thisdotnotexist.either'
Succeeded
*)

这里我将下载包装到另一个async中来捕获Uri构造异常。

关于F# 在 Async.Catch 上继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38537964/

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