@@ -11,14 +11,6 @@ module Task =
1111 open System.Threading
1212 open System.Threading .Tasks
1313 open FSharpPlus.Internals .Errors
14-
15- module private Unit =
16- /// Active pattern to match the state of a completed Task
17- let (| Succeeded | Canceled | Faulted |) ( t : Task ) =
18- if t.IsCompletedSuccessfully then Succeeded
19- elif t.IsFaulted then Faulted ( Unchecked.nonNull ( t.Exception))
20- elif t.IsCanceled then Canceled
21- else invalidOp " The task is not yet completed."
2214
2315 /// Active pattern to match the state of a completed Task
2416 let inline internal (| Succeeded | Canceled | Faulted |) ( t : Task < 'a >) =
@@ -37,23 +29,19 @@ module Task =
3729 /// <returns >A Task that is completed successfully with the specified value.</returns >
3830 let result ( value : 'T ) : Task < 'T > = Task.FromResult value
3931
40- /// <summary >Creates a Task that's completed unsuccessfully with the specified exception .</summary >
41- /// <param name =" exn " >The exception to be raised.</param >
42- /// <returns >A Task that is completed unsuccessfully with the specified exception .</returns >
32+ /// <summary >Creates a Task that's completed unsuccessfully with the specified exceptions .</summary >
33+ /// <param name =" exn " >The AggregateException to be raised.</param >
34+ /// <returns >A Task that is completed unsuccessfully with the specified exceptions .</returns >
4335 /// <remarks >
44- /// If the exception is not an AggregateException it is wrapped into one.
45- /// Prefer this function over Task.FromException as it handles AggregateExceptions correctly.
36+ /// Prefer this function to handle AggregateExceptions over Task.FromException as it handles them correctly.
4637 /// </remarks >
47- let raise < 'T > ( exn : exn ) : Task < 'T > =
48- match exn with
49- // AggregateException with multiple exceptions - use TCS
50- | :? AggregateException as agg when agg.InnerExceptions.Count > 1 ->
38+ let internal FromExceptions < 'T > ( aex : AggregateException ) : Task < 'T > =
39+ match aex with
40+ | agg when agg.InnerExceptions.Count = 1 -> Task.FromException < 'T > agg.InnerExceptions [ 0 ]
41+ | agg ->
5142 let tcs = TaskCompletionSource< 'T> ()
5243 tcs.SetException agg.InnerExceptions
5344 tcs.Task
54- // Single exception / Single non-aggregate exception -> use optimized path
55- | :? AggregateException as agg -> Task.FromException< 'T> agg.InnerExceptions[ 0 ]
56- | exn -> Task.FromException< 'T> exn
5745
5846 let private cancellationTokenSingleton = CancellationToken true
5947
@@ -85,10 +73,10 @@ module Task =
8573
8674 if x.IsCompleted && y.IsCompleted then
8775 match x, y with
88- | Succeeded r1, Succeeded r2 -> try result ( mapper r1 r2) with e -> raise e
89- | Succeeded _ , Faulted exn -> raise exn
76+ | Succeeded r1, Succeeded r2 -> try result ( mapper r1 r2) with e -> Task.FromException <_> e
77+ | Succeeded _ , Faulted exn -> FromExceptions exn
9078 | Succeeded _ , Canceled -> canceled
91- | Faulted exn , _ -> raise exn
79+ | Faulted exn , _ -> FromExceptions exn
9280 | Canceled , _ -> canceled
9381 else
9482 let tcs = TaskCompletionSource< 'U> ()
@@ -392,23 +380,22 @@ module Task =
392380 }
393381
394382 /// <summary >Creates a task that ignores the result of the source task.</summary >
383+ /// <param name =" source " >The source Task.</param >
384+ /// <returns >A Task that completes when the source completes.</returns >
395385 /// <remarks >It can be used to convert non-generic Task to unit Task.</remarks >
396- let ignore ( task : Task ) =
397- let task = nullArgCheck ( nameof task) task
398-
399- if task.IsCompleted then
400- let t = result ()
401- match task with
402- | Unit.Succeeded -> t
403- | Unit.Faulted e -> raise< unit> e
404- | Unit.Canceled -> canceled< unit>
386+ let ignore ( source : Task ) =
387+ let source = nullArgCheck ( nameof source) source
388+
389+ if source.IsCompletedSuccessfully then result ()
390+ elif source.IsFaulted then FromExceptions ( Unchecked.nonNull source.Exception)
391+ elif source.IsCanceled then canceled
405392 else
406393 let tcs = TaskCompletionSource< unit> ()
407- let k = function
408- | Unit.Succeeded -> tcs.SetResult ()
409- | Unit.Faulted e -> tcs.SetException e .InnerExceptions
410- | Unit.Canceled -> tcs.SetCanceled ()
411- task .ContinueWith k |> ignore
394+ let k ( t : Task ) : unit =
395+ if t.IsCanceled then tcs.SetCanceled ()
396+ elif t.IsFaulted then tcs.SetException ( Unchecked.nonNull source.Exception ) .InnerExceptions
397+ else tcs.SetResult ()
398+ source .ContinueWith k |> ignore
412399 tcs.Task
413400
414401 [<ObsoleteAttribute( " Swap parameters" ) >]
@@ -452,7 +439,10 @@ module Task =
452439
453440 orElseWith ( fun _ -> fallbackTask) source
454441
455-
442+ /// <summary >Creates a Task that's completed unsuccessfully with the specified exception.</summary >
443+ /// <param name =" exn " >The exception to be raised.</param >
444+ /// <returns >A Task that is completed unsuccessfully with the specified exception.</returns >
445+ let raise < 'T > ( exn : exn ) : Task < 'T > = Task.FromException< 'T> exn
456446
457447
458448/// Workaround to fix signatures without breaking binary compatibility.
0 commit comments