@@ -68,6 +68,55 @@ module Extensions =
6868
6969 #if ! FABLE_ COMPILER
7070
71+ /// <summary>Runs an asynchronous computation, starting immediately on the current operating system
72+ /// thread, but also returns the execution as <see cref="T:System.Threading.Tasks.Task`1"/>
73+ /// This behaves exactly like Async.StartImmediateAsTask but without unexpected exceptions-wrapping.
74+ /// </summary>
75+ ///
76+ /// <remarks>If no cancellation token is provided then the default cancellation token is used.
77+ /// You may prefer using this method if you want to achive a similar behviour to async await in C# as
78+ /// async computation starts on the current thread with an ability to return a result.
79+ /// </remarks>
80+ ///
81+ /// <param name="computation">The asynchronous computation to execute.</param>
82+ /// <param name="cancellationToken">The <c>CancellationToken</c> to associate with the computation.
83+ /// The default is used if this parameter is not provided.</param>
84+ ///
85+ /// <returns>A <see cref="T:System.Threading.Tasks.Task"/> that will be completed
86+ /// in the corresponding state once the computation terminates (produces the result, throws exception or gets canceled)</returns>
87+ ///
88+ /// <category index="0">FSharp.Core Extensions</category>
89+ ///
90+ /// <example id="as-task-1">
91+ /// <code lang="fsharp">
92+ /// printfn "A"
93+ ///
94+ /// let t =
95+ /// async {
96+ /// printfn "B"
97+ /// do! Async.Sleep(1000)
98+ /// printfn "C"
99+ /// } |> Async.AsTask
100+ ///
101+ /// printfn "D"
102+ /// t.Wait()
103+ /// printfn "E"
104+ /// </code>
105+ /// Prints "A", "B", "D" immediately, then "C", "E" in 1 second.
106+ /// </example>
107+ static member AsTask ( computation : Async < 'T >, ? cancellationToken ) : Task < 'T > =
108+ let cancellationToken = defaultArg cancellationToken ( new CancellationToken ())
109+ let ts = TaskCompletionSource< 'T> ()
110+ Async.StartWithContinuations (
111+ computation,
112+ ts.SetResult,
113+ ( function
114+ | :? AggregateException as agg -> ts.SetException agg.InnerExceptions
115+ | exn -> ts.SetException exn),
116+ ( fun _ -> ts.SetCanceled ()),
117+ cancellationToken)
118+ ts.Task
119+
71120 // See https://github.com/fsharp/fslang-suggestions/issues/840
72121
73122 /// <summary>Return an asynchronous computation that will wait for the given task to complete and return
@@ -126,12 +175,9 @@ module Extensions =
126175
127176
128177 /// Combine all asyncs in one, chaining them in sequence order.
129- static member Sequence ( t : seq < Async < _ >>) : Async < seq < _ >> = async {
130- let startImmediateAsTask ct a =
131- Async.StartImmediateAsTask( a, ct). Result
132-
178+ static member Sequence ( t : seq < Async < 'T >>) : Async < seq < _ >> = async {
133179 let! ct = Async.CancellationToken
134- return t |> Seq.map ( startImmediateAsTask ct) }
180+ return Seq.map ( fun t -> Async.AsTask ( t , ct). Result ) t }
135181 #endif
136182
137183 /// Combine all asyncs in one, chaining them in sequence order.
0 commit comments