Reputation: 781
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)
Upvotes: 0
Views: 242
Reputation: 16194
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";}
}
Upvotes: 2