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

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now