@@ -8,6 +8,11 @@ module ValueTask =
88
99 open System.Threading
1010 open System.Threading .Tasks
11+
12+ let inline internal (| Succeeded | Canceled | Faulted |) ( t : ValueTask < 'T >) =
13+ if t.IsCompletedSuccessfully then Succeeded t.Result
14+ elif t.IsCanceled then Canceled
15+ else Faulted ( t.AsTask() .Exception.InnerExceptions)
1116
1217 /// <summary>Creates a <see cref="ValueTask{TResult}"/> that's completed successfully with the specified result.</summary>
1318 /// <typeparam name="TResult">The type of the result returned by the task.</typeparam>
@@ -31,83 +36,103 @@ module ValueTask =
3136 /// <param name="source">Task workflow.</param>
3237 let FromTask < 'TResult > ( source : Task < 'TResult >) = ValueTask< 'TResult> source
3338
39+ let inline internal continueTask ( tcs : TaskCompletionSource < 'Result >) ( x : ValueTask < 't >) ( k : 't -> unit ) =
40+ let f = function
41+ | Succeeded r -> k r
42+ | Canceled -> tcs.SetCanceled ()
43+ | Faulted e -> tcs.SetException e
44+ if x.IsCompleted then f x
45+ else
46+ let aw = x.GetAwaiter ()
47+ aw.OnCompleted ( fun () -> f x)
48+
3449 /// <summary>Creates a ValueTask workflow from 'source' another, mapping its result with 'f'.</summary>
3550 let map ( f : 'T -> 'U ) ( source : ValueTask < 'T >) : ValueTask < 'U > =
36- backgroundTask {
37- let! r = source
38- return f r
39- } |> ValueTask< 'U>
51+ let tcs = TaskCompletionSource< 'U> ()
52+ continueTask tcs source ( fun x ->
53+ try tcs.SetResult ( f x)
54+ with e -> tcs.SetException e)
55+ tcs.Task |> ValueTask< 'U>
56+
4057
4158 /// <summary>Creates a ValueTask workflow from two workflows 'x' and 'y', mapping its results with 'f'.</summary>
4259 /// <remarks>Workflows are run in sequence.</remarks>
4360 /// <param name="f">The mapping function.</param>
4461 /// <param name="x">First ValueTask workflow.</param>
4562 /// <param name="y">Second ValueTask workflow.</param>
4663 let map2 ( f : 'T -> 'U -> 'V ) ( x : ValueTask < 'T >) ( y : ValueTask < 'U >) : ValueTask < 'V > =
47- backgroundTask {
48- let! rX = x
49- let! rY = y
50- return f rX rY
51- } |> ValueTask< 'V>
64+ let tcs = TaskCompletionSource< 'V> ()
65+ continueTask tcs x ( fun x ->
66+ continueTask tcs y ( fun y ->
67+ try tcs.SetResult ( f x y)
68+ with e -> tcs.SetException e))
69+ tcs.Task |> ValueTask< 'V>
5270
5371 /// <summary>Creates a ValueTask workflow from three workflows 'x', 'y' and z, mapping its results with 'f'.</summary>
5472 /// <remarks>Workflows are run in sequence.</remarks>
5573 /// <param name="f">The mapping function.</param>
5674 /// <param name="x">First ValueTask workflow.</param>
5775 /// <param name="y">Second ValueTask workflow.</param>
5876 /// <param name="z">Third ValueTask workflow.</param>
59- let map3 ( f : 'T -> 'U -> 'V -> 'W ) ( x : ValueTask < 'T >) ( y : ValueTask < 'U >) ( z : ValueTask < 'V >) : ValueTask < 'W > =
60- backgroundTask {
61- let! rX = x
62- let! rY = y
63- let! rZ = z
64- return f rX rY rZ
65- } |> ValueTask< 'W>
77+ let map3 ( f : 'T -> 'U -> 'V -> 'W ) ( x : ValueTask < 'T >) ( y : ValueTask < 'U >) ( z : ValueTask < 'V >) : ValueTask < 'W > =
78+ let tcs = TaskCompletionSource< 'W> ()
79+ continueTask tcs x ( fun x ->
80+ continueTask tcs y ( fun y ->
81+ continueTask tcs z ( fun z ->
82+ try tcs.SetResult ( f x y z)
83+ with e -> tcs.SetException e)))
84+ tcs.Task |> ValueTask< 'W>
6685
6786 /// <summary>Creates a ValueTask workflow that is the result of applying the resulting function of a ValueTask workflow
6887 /// to the resulting value of another ValueTask workflow</summary>
6988 /// <param name="f">ValueTask workflow returning a function</param>
7089 /// <param name="x">ValueTask workflow returning a value</param>
7190 let apply ( f : ValueTask < 'T -> 'U >) ( x : ValueTask < 'T >) : ValueTask < 'U > =
72- backgroundTask {
73- let! r = x
74- let! fn = f
75- return ( fn r)
76- } |> ValueTask< 'U>
91+ let tcs = TaskCompletionSource< 'U> ()
92+ continueTask tcs f ( fun f ->
93+ continueTask tcs x ( fun x ->
94+ try tcs.SetResult ( f x)
95+ with e -> tcs.SetException e))
96+ tcs.Task |> ValueTask< 'U>
7797
7898 /// <summary>Creates a ValueTask workflow from two workflows 'x' and 'y', tupling its results.</summary>
7999 let zip ( x : ValueTask < 'T >) ( y : ValueTask < 'U >) : ValueTask < 'T * 'U > =
80- backgroundTask {
81- let! rX = x
82- let! rY = y
83- return ( rX , rY )
84- } |> ValueTask< 'T * 'U>
100+ let tcs = TaskCompletionSource < 'T * 'U > ()
101+ continueTask tcs x ( fun x ->
102+ continueTask tcs y ( fun y ->
103+ tcs.SetResult ( x , y )) )
104+ tcs.Task |> ValueTask< 'T * 'U>
85105
86106 /// Flattens two nested ValueTask into one.
87107 let join ( source : ValueTask < ValueTask < 'T >>) : ValueTask < 'T > =
88- backgroundTask {
89- let! s = source
90- return ! s
91- } |> ValueTask< 'T>
108+ let tcs = TaskCompletionSource< 'T> ()
109+ continueTask tcs source ( fun x ->
110+ continueTask tcs x ( fun x ->
111+ tcs.SetResult x))
112+ tcs.Task |> ValueTask< 'T>
92113
93114
94115 /// <summary>Creates a ValueTask workflow from 'source' workflow, mapping and flattening its result with 'f'.</summary>
95116 let bind ( f : 'T -> ValueTask < 'U >) ( source : ValueTask < 'T >) : ValueTask < 'U > =
96- source
97- |> map f
98- |> join
117+ let tcs = TaskCompletionSource< 'U> ()
118+ continueTask tcs source ( fun x ->
119+ try
120+ continueTask tcs ( f x) ( fun fx ->
121+ tcs.SetResult fx)
122+ with e -> tcs.SetException e)
123+ tcs.Task |> ValueTask< 'U>
99124
100125 /// <summary>Creates a ValueTask that ignores the result of the source ValueTask.</summary>
101126 /// <remarks>It can be used to convert non-generic ValueTask to unit ValueTask.</remarks>
102127 let ignore ( source : ValueTask < 'T >) =
103- backgroundTask {
104- let! _ = source
105- return ()
106- } |> ValueTask
128+ if source.IsCompletedSuccessfully then
129+ source.GetAwaiter() .GetResult() |> ignore
130+ Unchecked.defaultof<_>
131+ else
132+ new ValueTask ( source.AsTask ())
107133
108134
109135 /// Raises an exception in the ValueTask
110- let raise ( e : exn ) =
111- FromException e
136+ let raise ( e : exn ) = FromException e
112137
113138#endif
0 commit comments