-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathAsyncExtensions.fs
More file actions
32 lines (27 loc) · 1.35 KB
/
AsyncExtensions.fs
File metadata and controls
32 lines (27 loc) · 1.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace FSharp.Control
[<AutoOpen>]
module AsyncExtensions =
// Awaits a Task<unit> without wrapping exceptions in AggregateException.
// Async.AwaitTask wraps task exceptions in AggregateException, which breaks try/catch
// blocks in async {} expressions that expect the original exception type.
// See: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/129
let private awaitTaskCorrect (task: System.Threading.Tasks.Task<unit>) : Async<unit> =
Async.FromContinuations(fun (cont, econt, ccont) ->
task.ContinueWith(fun (t: System.Threading.Tasks.Task<unit>) ->
if t.IsFaulted then
let exn = t.Exception
if exn.InnerExceptions.Count = 1 then
econt exn.InnerExceptions.[0]
else
econt exn
elif t.IsCanceled then
ccont (System.OperationCanceledException "The operation was cancelled.")
else
cont ())
|> ignore)
// Add asynchronous for loop to the 'async' computation builder
type Microsoft.FSharp.Control.AsyncBuilder with
member _.For(source: TaskSeq<'T>, action: 'T -> Async<unit>) =
source
|> TaskSeq.iterAsync (action >> Async.StartImmediateAsTask)
|> awaitTaskCorrect