Asynchronous function calls in Parallel

六月ゝ 毕业季﹏ 提交于 2019-12-25 00:25:06

问题


Following version is calling all functions synchronously,

I'm looking to find out how to call asynchronous functions in parallel and return all results and errors to the caller.

Request

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";}
    }

Test

[<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

Ideally to be able to match Ok and Error results while iterating through results

Edit based on the answer.

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


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

Attempt

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

Iteration using For in

for r in result do
    match r with
    | Ok re -> Console.WriteLine(re)
    | Error error -> Console.WriteLine(error)

回答1:


You can use Async.Parallel to run many async operations in 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.

There may be an issue with your requestAsync function return type, or a missing type definition in your example. Here's what I used to verify the solution:

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";}
    }


来源:https://stackoverflow.com/questions/49510938/asynchronous-function-calls-in-parallel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!