@@ -64,7 +64,67 @@ module Extensions =
6464
6565 type Async < 't > with
6666
67+ static member internal Map f x = async.Bind ( x, async.Return << f)
68+
6769 #if ! FABLE_ COMPILER
70+
71+ // See https://github.com/fsharp/fslang-suggestions/issues/840
72+
73+ /// <summary >Return an asynchronous computation that will wait for the given task to complete and return
74+ /// its result.</summary >
75+ ///
76+ /// <param name =" task " >The task to await.</param >
77+ ///
78+ /// <remarks >Prefer this over <c >Async.AwaitTask</c >.
79+ ///
80+ /// If an exception occurs in the asynchronous computation then an exception is re-raised by this function.
81+ ///
82+ /// If the task is cancelled then <see cref =" F:System.Threading.Tasks.TaskCanceledException " /> is raised. Note
83+ /// that the task may be governed by a different cancellation token to the overall async computation where the
84+ /// Await occurs. In practice you should normally start the task with the cancellation token returned by
85+ /// <c >let! ct = Async.CancellationToken</c >, and catch any <see cref =" F:System.Threading.Tasks.TaskCanceledException " />
86+ /// at the point where the overall async is started.
87+ /// </remarks >
88+ static member Await ( task : Task < 'T >) : Async < 'T > =
89+ Async.FromContinuations ( fun ( sc , ec , _ ) ->
90+ task.ContinueWith ( fun ( task : Task < 'T >) ->
91+ if task.IsFaulted then
92+ let e = task.Exception
93+ if e.InnerExceptions.Count = 1 then ec e.InnerExceptions[ 0 ]
94+ else ec e
95+ elif task.IsCanceled then ec ( TaskCanceledException ())
96+ else sc task.Result)
97+ |> ignore)
98+
99+
100+ /// <summary >Return an asynchronous computation that will wait for the given task to complete and return
101+ /// its result.</summary >
102+ ///
103+ /// <param name =" task " >The task to await.</param >
104+ ///
105+ /// <remarks >Prefer this over <c >Async.AwaitTask</c >.
106+ ///
107+ /// If an exception occurs in the asynchronous computation then an exception is re-raised by this function.
108+ ///
109+ /// If the task is cancelled then <see cref =" F:System.Threading.Tasks.TaskCanceledException " /> is raised. Note
110+ /// that the task may be governed by a different cancellation token to the overall async computation where the
111+ /// Await occurs. In practice you should normally start the task with the cancellation token returned by
112+ /// <c >let! ct = Async.CancellationToken</c >, and catch any <see cref =" F:System.Threading.Tasks.TaskCanceledException " />
113+ /// at the point where the overall async is started.
114+ /// </remarks >
115+ static member Await ( task : Task ) : Async < unit > =
116+ Async.FromContinuations ( fun ( sc , ec , _ ) ->
117+ task.ContinueWith ( fun ( task : Task ) ->
118+ if task.IsFaulted then
119+ let e = task.Exception
120+ if e.InnerExceptions.Count = 1 then ec e.InnerExceptions[ 0 ]
121+ else ec e
122+ elif task.IsCanceled then ec ( TaskCanceledException ())
123+ else sc ())
124+ |> ignore)
125+
126+
127+
68128 /// Combine all asyncs in one, chaining them in sequence order.
69129 static member Sequence ( t : seq < Async < _ >>) : Async < seq < _ >> = async {
70130 let startImmediateAsTask ct a =
@@ -102,26 +162,26 @@ module Extensions =
102162 /// Creates an async Result from a Result where the Ok case is async.
103163 static member Sequence ( t : Result < Async < 'T >, 'Error >) : Async < Result < 'T , 'Error >> =
104164 match t with
105- | Ok a -> Async.map Ok a
165+ | Ok a -> Async.Map Ok a
106166 | Error e -> async.Return ( Error e)
107167
108168 /// Creates an async Choice from a Choice where the Choice1Of2 case is async.
109169 static member Sequence ( t : Choice < Async < 'T >, 'Choice2Of2 >) : Async < Choice < 'T , 'Choice2Of2 >> =
110170 match t with
111- | Choice1Of2 a -> Async.map Choice1Of2 a
171+ | Choice1Of2 a -> Async.Map Choice1Of2 a
112172 | Choice2Of2 e -> async.Return ( Choice2Of2 e)
113173
114174 /// Creates an async Result from a Result where both cases are async.
115175 static member Bisequence ( t : Result < Async < 'T >, Async < 'Error >>) : Async < Result < 'T , 'Error >> =
116176 match t with
117- | Ok a -> Async.map Ok a
118- | Error e -> Async.map Error e
177+ | Ok a -> Async.Map Ok a
178+ | Error e -> Async.Map Error e
119179
120180 /// Creates an async Choice from a Choice where both cases are async.
121181 static member Bisequence ( t : Choice < Async < 'T >, Async < 'Choice2Of2 >>) : Async < Choice < 'T , 'Choice2Of2 >> =
122182 match t with
123- | Choice1Of2 a -> Async.map Choice1Of2 a
124- | Choice2Of2 e -> Async.map Choice2Of2 e
183+ | Choice1Of2 a -> Async.Map Choice1Of2 a
184+ | Choice2Of2 e -> Async.Map Choice2Of2 e
125185
126186 type Option < 't > with
127187
0 commit comments