2016-07-23 7 views
2

저는 많은 비동기 웹 요청을하고 Async.Parallel을 사용하고 있습니다. 다음과 같은 메시지가 표시됩니다.F # Async.Catch에서 계속

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

일부 요청은 예외를 throw 할 수 있습니다. 일부 요청이 로그에 남기고 나머지 URL을 계속 사용하려고합니다. Async.Catch 함수를 찾았지만 첫 번째 예외가 throw 될 때 계산이 중지됩니다. I know 전체 목록을 계산하기 위해 async 식 내에서 try...with 표현식을 사용할 수는 있지만, 이는 내 downloadAsync 함수에 로그 함수를 전달하여 해당 형식을 변경 함을 의미합니다. 예외를 잡아 로그에 남기고 다른 URL을 계속 사용하는 다른 방법이 있습니까?

다음
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 
*) 

내가 Uri 건설 예외를 캡처하는 또 다른 async로 다운로드를 포장 :

+1

당신의 질문은 나에게 불분명하다.'xs |> Seq.map (fun u -> Async.Catch <| downloadAsync u.Url) |> Async.Parallel' 이상으로 무엇을 원합니까? – ildjarn

+0

미안하지만 내 질문에 영어가 :(귀하의 의견에 코드가 나를 위해 작동합니다! 감사합니다 – Nicolocodev

답변

4

'트릭'잡기가 아니라 병렬되도록지도로 캐치를 이동하는 것입니다.

+0

예! 감사합니다! – Nicolocodev