并行

时间:2018-03-27 10:49:46

标签: parallel-processing f#

以下版本同步调用所有函数,

我正在寻找如何并行调用异步函数并将所有resultserrors返回给调用者。

请求

let requestAsync (url: string) : Async<Result<string, Error>> =
    async {
        Console.WriteLine ("Simulating request " + url)
        try
            do! Async.Sleep(1000)
            return Ok (url + ": body...")
        with :? WebException as e ->
            return Error {code = 500; message = "Internal Server Error";}
    }

测试

[<TestMethod>]
member this.TestrequestAsync() =
    let urls = [|
        "http://www.example.com/1";
        "http://www.example.com/2";
        "http://www.example.com/3";
        "http://www.example.com/4";
        "http://www.example.com/5";
        "http://www.example.com/6";
        "http://www.example.com/7";
        "http://www.example.com/8";
        "http://www.example.com/9";
        "http://www.example.com/10";
    |]

    urls
    |> Array.map (fun url -> requestAsync url |> Async.RunSynchronously) // Async.Parallel some mismatch

    // Iterate results

理想情况下,在迭代结果时能够匹配OkError结果

根据答案

修改

let result =
    urls
    |> Seq.map Entity.requestDetailAsync2
    |> Async.Parallel
    |> Async.RunSynchronously


result
|> Array.iter Console.WriteLine // match x with Ok and Error?

尝试

result |> Array.iter (fun data -> match data with
                                      | Ok result -> Console.WriteLine(result)
                                      | Error error -> Console.WriteLine(error) )

中使用For进行迭代
for r in result do
    match r with
    | Ok re -> Console.WriteLine(re)
    | Error error -> Console.WriteLine(error)

1 个答案:

答案 0 :(得分:2)

您可以使用Async.Parallel并行运行多个异步操作:

let results =
  urls
  |> Seq.map requestAsync   // seq<Async<'T>>
  |> Async.Parallel         // async<T' []>
  |> Async.RunSynchronously // T' []

Here's a very similar example on MSDN.

您的requestAsync函数返回类型可能存在问题,或者示例中缺少类型定义。以下是我用来验证解决方案的内容:

type RequestError = {
  code : int
  message : string
}

let requestAsync (url: string) =
    async {
        Console.WriteLine ("Simulating request " + url)
        try
            do! Async.Sleep(1000)
            return Ok (url + ": body...")
        with :? WebException as e ->
            return Error {code = 500; message = "Internal Server Error";}
    }