Mercurial > pub > ImplabNet
annotate Implab/PromiseExtensions.cs @ 207:558f34b2fb50 v2
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
added Safe.Dispose(IEnumerable)
added PromiseExtensions.CancellationPoint to add a cancellation point to the chain of promises
added IPromise<T> PromiseExtensions.Then<T>(this IPromise<T> that, Action<T> success) overloads
added PromiseExtensions.Error() overloads to handle a error or(and) a cancellation
author | cin |
---|---|
date | Wed, 09 Nov 2016 12:03:22 +0300 |
parents | 8200ab154c8a |
children | 7d07503621fe |
rev | line source |
---|---|
72 | 1 using System.Threading; |
75 | 2 using System; |
109 | 3 using Implab.Diagnostics; |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
4 using System.Collections.Generic; |
205
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
5 using System.Linq; |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
6 |
72 | 7 namespace Implab { |
8 public static class PromiseExtensions { | |
9 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) { | |
75 | 10 Safe.ArgumentNotNull(that, "that"); |
72 | 11 var context = SynchronizationContext.Current; |
12 if (context == null) | |
13 return that; | |
14 | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
15 var p = new SyncContextPromise<T>(context); |
185 | 16 p.CancellationRequested(that.Cancel); |
72 | 17 |
104 | 18 that.On( |
76 | 19 p.Resolve, |
20 p.Reject, | |
185 | 21 p.CancelOperation |
72 | 22 ); |
23 return p; | |
24 } | |
25 | |
26 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) { | |
75 | 27 Safe.ArgumentNotNull(that, "that"); |
72 | 28 Safe.ArgumentNotNull(context, "context"); |
29 | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
30 var p = new SyncContextPromise<T>(context); |
185 | 31 p.CancellationRequested(that.Cancel); |
72 | 32 |
104 | 33 that.On( |
76 | 34 p.Resolve, |
35 p.Reject, | |
185 | 36 p.CancelOperation |
72 | 37 ); |
38 return p; | |
39 } | |
75 | 40 |
101 | 41 /// <summary> |
42 /// Ensures the dispatched. | |
43 /// </summary> | |
44 /// <returns>The dispatched.</returns> | |
45 /// <param name="that">That.</param> | |
46 /// <param name="head">Head.</param> | |
47 /// <param name="cleanup">Cleanup.</param> | |
48 /// <typeparam name="TPromise">The 1st type parameter.</typeparam> | |
49 /// <typeparam name="T">The 2nd type parameter.</typeparam> | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
50 public static TPromise EnsureDispatched<TPromise, T>(this TPromise that, IPromise<T> head, Action<T> cleanup) where TPromise : IPromise { |
101 | 51 Safe.ArgumentNotNull(that, "that"); |
52 Safe.ArgumentNotNull(head, "head"); | |
53 | |
138
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
54 that.On(() => head.On(cleanup), PromiseEventType.Cancelled); |
101 | 55 |
56 return that; | |
57 } | |
58 | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
59 /// <summary> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
60 /// Adds a cancellation point to the chain of promises. When a cancellation request reaches the cancellation point the operation is |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
61 /// cancelled immediatelly, and the request is passed towards. If the operation at the higher level can not be cancelled is't result |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
62 /// will be collected with <paramref name="cleanup"/> callback. |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
63 /// </summary> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
64 /// <typeparam name="T">The type of the promise result.</typeparam> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
65 /// <param name="that">The promise to which the cancellation point should be attached.</param> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
66 /// <param name="cleanup">The callback which is used to cleanup the result of the operation if the cancellation point is cancelled already.</param> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
67 /// <returns>The promise</returns> |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
68 public static IPromise<T> CancellationPoint<T>(this IPromise<T> that, Action<T> cleanup) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
69 var meduim = new Promise<T>(); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
70 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
71 that.On(meduim.Resolve, meduim.Reject, meduim.CancelOperation); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
72 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
73 meduim.CancellationRequested(that.Cancel); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
74 meduim.CancellationRequested(meduim.CancelOperation); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
75 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
76 if (cleanup != null) |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
77 meduim.On((Action<T>)null, null, (e) => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
78 that.On(cleanup); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
79 }); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
80 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
81 return meduim; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
82 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
83 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
84 public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult, T> callback) { |
75 | 85 Safe.ArgumentNotNull(that, "that"); |
86 Safe.ArgumentNotNull(callback, "callback"); | |
109 | 87 var op = TraceContext.Instance.CurrentOperation; |
75 | 88 return ar => { |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
89 TraceContext.Instance.EnterLogicalOperation(op, false); |
75 | 90 try { |
91 that.Resolve(callback(ar)); | |
92 } catch (Exception err) { | |
93 that.Reject(err); | |
109 | 94 } finally { |
95 TraceContext.Instance.Leave(); | |
75 | 96 } |
97 }; | |
98 } | |
110 | 99 |
185 | 100 static void CancelByTimeoutCallback(object cookie) { |
101 ((ICancellable)cookie).Cancel(new TimeoutException()); | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
102 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
103 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
104 /// <summary> |
110 | 105 /// Cancells promise after the specified timeout is elapsed. |
106 /// </summary> | |
107 /// <param name="that">The promise to cancel on timeout.</param> | |
108 /// <param name="milliseconds">The timeout in milliseconds.</param> | |
109 /// <typeparam name="TPromise">The 1st type parameter.</typeparam> | |
110 public static TPromise Timeout<TPromise>(this TPromise that, int milliseconds) where TPromise : IPromise { | |
111 Safe.ArgumentNotNull(that, "that"); | |
185 | 112 var timer = new Timer(CancelByTimeoutCallback, that, milliseconds, -1); |
110 | 113 that.On(timer.Dispose, PromiseEventType.All); |
114 return that; | |
115 } | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
116 |
205
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
117 public static IPromise PromiseAll(this IEnumerable<IPromise> that) { |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
118 Safe.ArgumentNotNull(that, "that"); |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
119 return PromiseAll(that.ToList()); |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
120 } |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
121 |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
122 public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that) { |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
123 Safe.ArgumentNotNull(that, "that"); |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
124 return PromiseAll(that.ToList()); |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
125 } |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
126 |
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
127 public static IPromise PromiseAll(this ICollection<IPromise> that) { |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
128 Safe.ArgumentNotNull(that, "that"); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
129 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
130 int count = that.Count; |
124 | 131 int errors = 0; |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
132 var medium = new Promise(); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
133 |
136 | 134 if (count == 0) { |
135 medium.Resolve(); | |
136 return medium; | |
137 } | |
138 | |
124 | 139 medium.On(() => { |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
140 foreach (var p2 in that) |
124 | 141 p2.Cancel(); |
142 }, PromiseEventType.ErrorOrCancel); | |
143 | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
144 foreach (var p in that) |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
145 p.On( |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
146 () => { |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
147 if (Interlocked.Decrement(ref count) == 0) |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
148 medium.Resolve(); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
149 }, |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
150 error => { |
124 | 151 if (Interlocked.Increment(ref errors) == 1) |
152 medium.Reject( | |
153 new Exception("The dependency promise is failed", error) | |
154 ); | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
155 }, |
138
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
156 reason => { |
124 | 157 if (Interlocked.Increment(ref errors) == 1) |
138
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
158 medium.Cancel( |
124 | 159 new Exception("The dependency promise is cancelled") |
160 ); | |
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
161 } |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
162 ); |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
163 |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
164 return medium; |
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
110
diff
changeset
|
165 } |
124 | 166 |
205
8200ab154c8a
Added ResetState to RunnableComponent to reset in case of failure
cin
parents:
185
diff
changeset
|
167 public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that) { |
124 | 168 Safe.ArgumentNotNull(that, "that"); |
169 | |
170 int count = that.Count; | |
171 int errors = 0; | |
172 var medium = new Promise<T[]>(); | |
173 var results = new T[that.Count]; | |
174 | |
175 medium.On(() => { | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
176 foreach (var p2 in that) |
124 | 177 p2.Cancel(); |
178 }, PromiseEventType.ErrorOrCancel); | |
179 | |
180 int i = 0; | |
181 foreach (var p in that) { | |
182 var idx = i; | |
183 p.On( | |
184 x => { | |
185 results[idx] = x; | |
186 if (Interlocked.Decrement(ref count) == 0) | |
187 medium.Resolve(results); | |
188 }, | |
189 error => { | |
190 if (Interlocked.Increment(ref errors) == 1) | |
191 medium.Reject( | |
192 new Exception("The dependency promise is failed", error) | |
193 ); | |
194 }, | |
138
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
195 reason => { |
124 | 196 if (Interlocked.Increment(ref errors) == 1) |
138
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
197 medium.Cancel( |
f75cfa58e3d4
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents:
136
diff
changeset
|
198 new Exception("The dependency promise is cancelled", reason) |
124 | 199 ); |
200 } | |
201 ); | |
202 i++; | |
203 } | |
204 | |
205 return medium; | |
206 } | |
145 | 207 |
208 public static IPromise Then(this IPromise that, Action success, Action<Exception> error, Action<Exception> cancel) { | |
209 Safe.ArgumentNotNull(that, "that"); | |
210 | |
149 | 211 var d = new ActionTask(success, error, cancel, false); |
145 | 212 that.On(d.Resolve, d.Reject, d.CancelOperation); |
185 | 213 d.CancellationRequested(that.Cancel); |
145 | 214 return d; |
215 } | |
216 | |
217 public static IPromise Then(this IPromise that, Action success, Action<Exception> error) { | |
218 return Then(that, success, error, null); | |
219 } | |
220 | |
221 public static IPromise Then(this IPromise that, Action success) { | |
222 return Then(that, success, null, null); | |
223 } | |
224 | |
225 public static IPromise<T> Then<T>(this IPromise that, Func<T> success, Func<Exception, T> error, Func<Exception, T> cancel) { | |
226 Safe.ArgumentNotNull(that, "that"); | |
227 | |
149 | 228 var d = new FuncTask<T>(success, error, cancel, false); |
145 | 229 that.On(d.Resolve, d.Reject, d.CancelOperation); |
185 | 230 d.CancellationRequested(that.Cancel); |
145 | 231 return d; |
232 } | |
233 | |
234 public static IPromise<T> Then<T>(this IPromise that, Func<T> success, Func<Exception, T> error) { | |
235 return Then(that, success, error, null); | |
236 } | |
237 | |
238 public static IPromise<T> Then<T>(this IPromise that, Func<T> success) { | |
239 return Then(that, success, null, null); | |
240 } | |
241 | |
242 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success, Func<Exception, T2> error, Func<Exception, T2> cancel) { | |
243 Safe.ArgumentNotNull(that, "that"); | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
244 var d = new FuncTask<T, T2>(success, error, cancel, false); |
145 | 245 that.On(d.Resolve, d.Reject, d.CancelOperation); |
185 | 246 d.CancellationRequested(that.Cancel); |
145 | 247 return d; |
248 } | |
249 | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
250 public static IPromise<T> Then<T>(this IPromise<T> that, Action<T> success, Func<Exception, T> error, Func<Exception, T> cancel) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
251 Safe.ArgumentNotNull(that, "that"); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
252 var d = new FuncTask<T, T>( |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
253 x => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
254 success(x); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
255 return x; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
256 }, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
257 error, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
258 cancel, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
259 false |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
260 ); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
261 that.On(d.Resolve, d.Reject, d.CancelOperation); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
262 d.CancellationRequested(that.Cancel); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
263 return d; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
264 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
265 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
266 public static IPromise<T> Then<T>(this IPromise<T> that, Action<T> success, Func<Exception, T> error) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
267 return Then(that, success, error, null); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
268 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
269 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
270 public static IPromise<T> Then<T>(this IPromise<T> that, Action<T> success) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
271 return Then(that, success, null, null); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
272 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
273 |
145 | 274 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success, Func<Exception, T2> error) { |
275 return Then(that, success, error, null); | |
276 } | |
277 | |
278 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success) { | |
279 return Then(that, success, null, null); | |
280 } | |
281 | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
282 public static IPromise<T> Always<T>(this IPromise<T> that, Action handler) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
283 Func<Exception, T> errorOrCancel; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
284 if (handler != null) |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
285 errorOrCancel = e => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
286 handler(); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
287 throw new PromiseTransientException(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
288 }; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
289 else |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
290 errorOrCancel = null; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
291 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
292 return Then( |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
293 that, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
294 x => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
295 handler(); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
296 return x; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
297 }, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
298 errorOrCancel, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
299 errorOrCancel); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
300 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
301 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
302 public static IPromise Always(this IPromise that, Action handler) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
303 Action<Exception> errorOrCancel; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
304 if (handler != null) |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
305 errorOrCancel = e => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
306 handler(); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
307 throw new PromiseTransientException(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
308 }; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
309 else |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
310 errorOrCancel = null; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
311 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
312 return Then( |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
313 that, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
314 handler, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
315 errorOrCancel, |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
316 errorOrCancel); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
317 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
318 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
319 public static IPromise Error(this IPromise that, Action<Exception> handler, bool handleCancellation) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
320 Action<Exception> errorOrCancel; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
321 if (handler != null) |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
322 errorOrCancel = e => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
323 handler(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
324 throw new PromiseTransientException(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
325 }; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
326 else |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
327 errorOrCancel = null; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
328 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
329 return Then(that, null, errorOrCancel, handleCancellation ? errorOrCancel : null); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
330 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
331 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
332 public static IPromise Error(this IPromise that, Action<Exception> handler) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
333 return Error(that, handler, false); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
334 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
335 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
336 public static IPromise<T> Error<T>(this IPromise<T> that, Action<Exception> handler, bool handleCancellation) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
337 Func<Exception, T> errorOrCancel; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
338 if (handler != null) |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
339 errorOrCancel = e => { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
340 handler(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
341 throw new PromiseTransientException(e); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
342 }; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
343 else |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
344 errorOrCancel = null; |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
345 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
346 return Then(that, null, errorOrCancel, handleCancellation ? errorOrCancel : null); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
347 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
348 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
349 public static IPromise<T> Error<T>(this IPromise<T> that, Action<Exception> handler) { |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
350 return Error(that, handler, false); |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
351 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
352 |
145 | 353 #region chain traits |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
354 public static IPromise Chain(this IPromise that, Func<IPromise> success, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel) { |
145 | 355 Safe.ArgumentNotNull(that, "that"); |
356 | |
149 | 357 var d = new ActionChainTask(success, error, cancel, false); |
145 | 358 that.On(d.Resolve, d.Reject, d.CancelOperation); |
185 | 359 d.CancellationRequested(that.Cancel); |
145 | 360 return d; |
361 } | |
362 | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
363 public static IPromise Chain(this IPromise that, Func<IPromise> success, Func<Exception, IPromise> error) { |
145 | 364 return Chain(that, success, error, null); |
365 } | |
366 | |
367 public static IPromise Chain(this IPromise that, Func<IPromise> success) { | |
368 return Chain(that, success, null, null); | |
369 } | |
370 | |
371 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success, Func<Exception, IPromise<T>> error, Func<Exception, IPromise<T>> cancel) { | |
372 Safe.ArgumentNotNull(that, "that"); | |
373 | |
149 | 374 var d = new FuncChainTask<T>(success, error, cancel, false); |
145 | 375 that.On(d.Resolve, d.Reject, d.CancelOperation); |
376 if (success != null) | |
377 d.CancellationRequested(that.Cancel); | |
378 return d; | |
379 } | |
380 | |
381 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success, Func<Exception, IPromise<T>> error) { | |
382 return Chain(that, success, error, null); | |
383 } | |
384 | |
385 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success) { | |
386 return Chain(that, success, null, null); | |
387 } | |
388 | |
389 public static IPromise<T2> Chain<T, T2>(this IPromise<T> that, Func<T, IPromise<T2>> success, Func<Exception, IPromise<T2>> error, Func<Exception, IPromise<T2>> cancel) { | |
390 Safe.ArgumentNotNull(that, "that"); | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
391 var d = new FuncChainTask<T, T2>(success, error, cancel, false); |
145 | 392 that.On(d.Resolve, d.Reject, d.CancelOperation); |
393 if (success != null) | |
394 d.CancellationRequested(that.Cancel); | |
395 return d; | |
396 } | |
397 | |
398 public static IPromise<T2> Chain<T, T2>(this IPromise<T> that, Func<T, IPromise<T2>> success, Func<Exception, IPromise<T2>> error) { | |
399 return Chain(that, success, error, null); | |
400 } | |
401 | |
402 public static IPromise<T2> Chain<T, T2>(this IPromise<T> that, Func<T, IPromise<T2>> success) { | |
403 return Chain(that, success, null, null); | |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
404 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
405 |
145 | 406 #endregion |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
407 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
408 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
409 #if NET_4_5 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
410 |
151 | 411 public static PromiseAwaiter<T> GetAwaiter<T>(this IPromise<T> that) { |
75 | 412 Safe.ArgumentNotNull(that, "that"); |
413 | |
151 | 414 return new PromiseAwaiter<T>(that); |
207
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
415 } |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
416 |
558f34b2fb50
added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents:
205
diff
changeset
|
417 #endif |
72 | 418 } |
419 } | |
420 |