@@ -64,7 +64,67 @@ module Extensions =
64
64
65
65
type Async < 't > with
66
66
67
+ static member internal Map f x = async.Bind ( x, async.Return << f)
68
+
67
69
#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
+
68
128
/// Combine all asyncs in one, chaining them in sequence order.
69
129
static member Sequence ( t : seq < Async < _ >>) : Async < seq < _ >> = async {
70
130
let startImmediateAsTask ct a =
@@ -102,26 +162,26 @@ module Extensions =
102
162
/// Creates an async Result from a Result where the Ok case is async.
103
163
static member Sequence ( t : Result < Async < 'T >, 'Error >) : Async < Result < 'T , 'Error >> =
104
164
match t with
105
- | Ok a -> Async.map Ok a
165
+ | Ok a -> Async.Map Ok a
106
166
| Error e -> async.Return ( Error e)
107
167
108
168
/// Creates an async Choice from a Choice where the Choice1Of2 case is async.
109
169
static member Sequence ( t : Choice < Async < 'T >, 'Choice2Of2 >) : Async < Choice < 'T , 'Choice2Of2 >> =
110
170
match t with
111
- | Choice1Of2 a -> Async.map Choice1Of2 a
171
+ | Choice1Of2 a -> Async.Map Choice1Of2 a
112
172
| Choice2Of2 e -> async.Return ( Choice2Of2 e)
113
173
114
174
/// Creates an async Result from a Result where both cases are async.
115
175
static member Bisequence ( t : Result < Async < 'T >, Async < 'Error >>) : Async < Result < 'T , 'Error >> =
116
176
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
119
179
120
180
/// Creates an async Choice from a Choice where both cases are async.
121
181
static member Bisequence ( t : Choice < Async < 'T >, Async < 'Choice2Of2 >>) : Async < Choice < 'T , 'Choice2Of2 >> =
122
182
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
125
185
126
186
type Option < 't > with
127
187
0 commit comments