@@ -8,6 +8,11 @@ module ValueTask =
8
8
9
9
open System.Threading
10
10
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)
11
16
12
17
/// <summary>Creates a <see cref="ValueTask{TResult}"/> that's completed successfully with the specified result.</summary>
13
18
/// <typeparam name="TResult">The type of the result returned by the task.</typeparam>
@@ -31,83 +36,103 @@ module ValueTask =
31
36
/// <param name="source">Task workflow.</param>
32
37
let FromTask < 'TResult > ( source : Task < 'TResult >) = ValueTask< 'TResult> source
33
38
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
+
34
49
/// <summary>Creates a ValueTask workflow from 'source' another, mapping its result with 'f'.</summary>
35
50
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
+
40
57
41
58
/// <summary>Creates a ValueTask workflow from two workflows 'x' and 'y', mapping its results with 'f'.</summary>
42
59
/// <remarks>Workflows are run in sequence.</remarks>
43
60
/// <param name="f">The mapping function.</param>
44
61
/// <param name="x">First ValueTask workflow.</param>
45
62
/// <param name="y">Second ValueTask workflow.</param>
46
63
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>
52
70
53
71
/// <summary>Creates a ValueTask workflow from three workflows 'x', 'y' and z, mapping its results with 'f'.</summary>
54
72
/// <remarks>Workflows are run in sequence.</remarks>
55
73
/// <param name="f">The mapping function.</param>
56
74
/// <param name="x">First ValueTask workflow.</param>
57
75
/// <param name="y">Second ValueTask workflow.</param>
58
76
/// <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>
66
85
67
86
/// <summary>Creates a ValueTask workflow that is the result of applying the resulting function of a ValueTask workflow
68
87
/// to the resulting value of another ValueTask workflow</summary>
69
88
/// <param name="f">ValueTask workflow returning a function</param>
70
89
/// <param name="x">ValueTask workflow returning a value</param>
71
90
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>
77
97
78
98
/// <summary>Creates a ValueTask workflow from two workflows 'x' and 'y', tupling its results.</summary>
79
99
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>
85
105
86
106
/// Flattens two nested ValueTask into one.
87
107
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>
92
113
93
114
94
115
/// <summary>Creates a ValueTask workflow from 'source' workflow, mapping and flattening its result with 'f'.</summary>
95
116
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>
99
124
100
125
/// <summary>Creates a ValueTask that ignores the result of the source ValueTask.</summary>
101
126
/// <remarks>It can be used to convert non-generic ValueTask to unit ValueTask.</remarks>
102
127
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 ())
107
133
108
134
109
135
/// Raises an exception in the ValueTask
110
- let raise ( e : exn ) =
111
- FromException e
136
+ let raise ( e : exn ) = FromException e
112
137
113
138
#endif
0 commit comments