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 |
