@@ -0,0 +1,19 | |||||
|
1 | using System; | |||
|
2 | ||||
|
3 | namespace Implab { | |||
|
4 | [Flags] | |||
|
5 | public enum PromiseEventType { | |||
|
6 | Success = 1, | |||
|
7 | Error = 2, | |||
|
8 | Cancelled = 4, | |||
|
9 | /// <summary> | |||
|
10 | /// Завершено успешно, либо возникла ошибка, | |||
|
11 | /// </summary> | |||
|
12 | All = 7, | |||
|
13 | /// <summary> | |||
|
14 | /// Заврешено успешно, либо возникла ошибка. | |||
|
15 | /// </summary> | |||
|
16 | Complete = 3 | |||
|
17 | } | |||
|
18 | } | |||
|
19 |
@@ -29,7 +29,7 namespace Implab.Fx | |||||
29 |
|
29 | |||
30 | var directed = new ControlBoundPromise<T>(ctl,that); |
|
30 | var directed = new ControlBoundPromise<T>(ctl,that); | |
31 |
|
31 | |||
32 |
that. |
|
32 | that.On( | |
33 | directed.Resolve, |
|
33 | directed.Resolve, | |
34 | directed.Reject, |
|
34 | directed.Reject, | |
35 | directed.Cancel |
|
35 | directed.Cancel |
@@ -41,9 +41,10 namespace Implab { | |||||
41 | /// <param name="success">Success.</param> |
|
41 | /// <param name="success">Success.</param> | |
42 | /// <param name="error">Error.</param> |
|
42 | /// <param name="error">Error.</param> | |
43 | /// <param name="cancel">Cancel.</param> |
|
43 | /// <param name="cancel">Cancel.</param> | |
44 |
void |
|
44 | void On(Action success, Action<Exception> error, Action cancel); | |
45 |
void |
|
45 | void On(Action success, Action<Exception> error); | |
46 |
void |
|
46 | void On(Action success); | |
|
47 | void On(Action success, PromiseEventType events); | |||
47 |
|
48 | |||
48 | IPromise Error(Action<Exception> error); |
|
49 | IPromise Error(Action<Exception> error); | |
49 | /// <summary> |
|
50 | /// <summary> |
@@ -7,11 +7,11 namespace Implab { | |||||
7 |
|
7 | |||
8 | new T Join(int timeout); |
|
8 | new T Join(int timeout); | |
9 |
|
9 | |||
10 |
void |
|
10 | void On(Action<T> success, Action<Exception> error, Action cancel); | |
11 |
|
11 | |||
12 |
void |
|
12 | void On(Action<T> success, Action<Exception> error); | |
13 |
|
13 | |||
14 |
void |
|
14 | void On(Action<T> success); | |
15 |
|
15 | |||
16 | IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel); |
|
16 | IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel); | |
17 |
|
17 |
@@ -147,6 +147,7 | |||||
147 | <Compile Include="Diagnostics\Extensions.cs" /> |
|
147 | <Compile Include="Diagnostics\Extensions.cs" /> | |
148 | <Compile Include="IComponentContainer.cs" /> |
|
148 | <Compile Include="IComponentContainer.cs" /> | |
149 | <Compile Include="MTComponentContainer.cs" /> |
|
149 | <Compile Include="MTComponentContainer.cs" /> | |
|
150 | <Compile Include="PromiseEventType.cs" /> | |||
150 | </ItemGroup> |
|
151 | </ItemGroup> | |
151 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
|
152 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | |
152 | <ItemGroup /> |
|
153 | <ItemGroup /> |
@@ -183,7 +183,7 namespace Implab.Parallels { | |||||
183 | Monitor.Pulse(locker); |
|
183 | Monitor.Pulse(locker); | |
184 | } |
|
184 | } | |
185 | }) |
|
185 | }) | |
186 |
. |
|
186 | .On( | |
187 | x => { |
|
187 | x => { | |
188 | res[idx] = x; |
|
188 | res[idx] = x; | |
189 | var left = Interlocked.Decrement(ref pending); |
|
189 | var left = Interlocked.Decrement(ref pending); |
@@ -117,7 +117,8 namespace Implab { | |||||
117 | if (parent.IsExclusive) |
|
117 | if (parent.IsExclusive) | |
118 | parent.Cancel(); |
|
118 | parent.Cancel(); | |
119 | }, |
|
119 | }, | |
120 | null |
|
120 | null, | |
|
121 | false | |||
121 | ); |
|
122 | ); | |
122 | } |
|
123 | } | |
123 |
|
124 | |||
@@ -220,7 +221,7 namespace Implab { | |||||
220 |
|
221 | |||
221 | var medium = new Promise<T>(this); |
|
222 | var medium = new Promise<T>(this); | |
222 |
|
223 | |||
223 | AddHandler(success, error, cancel, medium); |
|
224 | AddHandler(success, error, cancel, medium, true); | |
224 |
|
225 | |||
225 | return medium; |
|
226 | return medium; | |
226 | } |
|
227 | } | |
@@ -238,7 +239,7 namespace Implab { | |||||
238 |
|
239 | |||
239 | var medium = new Promise<T>(this); |
|
240 | var medium = new Promise<T>(this); | |
240 |
|
241 | |||
241 | AddHandler(success, error, null, medium); |
|
242 | AddHandler(success, error, null, medium, true); | |
242 |
|
243 | |||
243 | return medium; |
|
244 | return medium; | |
244 | } |
|
245 | } | |
@@ -252,7 +253,7 namespace Implab { | |||||
252 |
|
253 | |||
253 | var medium = new Promise<T>(this); |
|
254 | var medium = new Promise<T>(this); | |
254 |
|
255 | |||
255 | AddHandler(success, null, null, medium); |
|
256 | AddHandler(success, null, null, medium, true); | |
256 |
|
257 | |||
257 | return medium; |
|
258 | return medium; | |
258 | } |
|
259 | } | |
@@ -274,7 +275,7 namespace Implab { | |||||
274 | /// всей цепи обещаний снизу (с самого последнего обещания). |
|
275 | /// всей цепи обещаний снизу (с самого последнего обещания). | |
275 | /// </para> |
|
276 | /// </para> | |
276 | /// </remarks> |
|
277 | /// </remarks> | |
277 |
public void |
|
278 | public void On(Action<T> success, Action<Exception> error, Action cancel) { | |
278 | if (success == null && error == null && cancel == null) |
|
279 | if (success == null && error == null && cancel == null) | |
279 | return; |
|
280 | return; | |
280 |
|
281 | |||
@@ -284,15 +285,28 namespace Implab { | |||||
284 | error(err); |
|
285 | error(err); | |
285 | return default(T); |
|
286 | return default(T); | |
286 | }; |
|
287 | }; | |
287 | AddHandler(success, errorHandler, cancel, null); |
|
288 | AddHandler(success, errorHandler, cancel, null, false); | |
|
289 | } | |||
|
290 | ||||
|
291 | public void On(Action<T> success, Action<Exception> error) { | |||
|
292 | On(success, error, null); | |||
|
293 | } | |||
|
294 | ||||
|
295 | public void On(Action<T> success) { | |||
|
296 | On(success, null, null); | |||
288 | } |
|
297 | } | |
289 |
|
298 | |||
290 | public void Last(Action<T> success, Action<Exception> error) { |
|
299 | public void On(Action handler, PromiseEventType events) { | |
291 | Last(success, error, null); |
|
300 | Safe.ArgumentNotNull(handler, "handler"); | |
292 | } |
|
|||
293 |
|
301 | |||
294 | public void Last(Action<T> success) { |
|
302 | Action<T> success = events.HasFlag(PromiseEventType.Success) ? new Action<T>(x => handler()) : null; | |
295 | Last(success, null, null); |
|
303 | Func<Exception,T> error = events.HasFlag(PromiseEventType.Error) ? new Func<Exception,T>(e => { | |
|
304 | handler(); | |||
|
305 | return default(T); | |||
|
306 | }) : null; | |||
|
307 | Action cancel = events.HasFlag(PromiseEventType.Cancelled) ? handler : null; | |||
|
308 | ||||
|
309 | AddHandler(success, error, cancel, null, false); | |||
296 | } |
|
310 | } | |
297 |
|
311 | |||
298 | public IPromise Error(Action<Exception> error) { |
|
312 | public IPromise Error(Action<Exception> error) { | |
@@ -308,7 +322,8 namespace Implab { | |||||
308 | return default(T); |
|
322 | return default(T); | |
309 | }, |
|
323 | }, | |
310 | null, |
|
324 | null, | |
311 | medium |
|
325 | medium, | |
|
326 | true | |||
312 | ); |
|
327 | ); | |
313 |
|
328 | |||
314 | return medium; |
|
329 | return medium; | |
@@ -328,7 +343,7 namespace Implab { | |||||
328 |
|
343 | |||
329 | var medium = new Promise<T>(this); |
|
344 | var medium = new Promise<T>(this); | |
330 |
|
345 | |||
331 | AddHandler(null, handler, null, medium); |
|
346 | AddHandler(null, handler, null, medium, true); | |
332 |
|
347 | |||
333 | return medium; |
|
348 | return medium; | |
334 | } |
|
349 | } | |
@@ -380,7 +395,8 namespace Implab { | |||||
380 | resultHandler, |
|
395 | resultHandler, | |
381 | errorHandler, |
|
396 | errorHandler, | |
382 | cancelHandler, |
|
397 | cancelHandler, | |
383 | null |
|
398 | null, | |
|
399 | true | |||
384 | ); |
|
400 | ); | |
385 |
|
401 | |||
386 | return medium; |
|
402 | return medium; | |
@@ -421,7 +437,7 namespace Implab { | |||||
421 |
|
437 | |||
422 | var promise = chained(result); |
|
438 | var promise = chained(result); | |
423 |
|
439 | |||
424 |
promise. |
|
440 | promise.On( | |
425 | medium.Resolve, |
|
441 | medium.Resolve, | |
426 | medium.Reject, |
|
442 | medium.Reject, | |
427 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка |
|
443 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
@@ -430,7 +446,7 namespace Implab { | |||||
430 | // notify chained operation that it's not needed anymore |
|
446 | // notify chained operation that it's not needed anymore | |
431 | // порядок вызова Then, Cancelled важен, поскольку от этого |
|
447 | // порядок вызова Then, Cancelled важен, поскольку от этого | |
432 | // зависит IsExclusive |
|
448 | // зависит IsExclusive | |
433 |
medium. |
|
449 | medium.On( | |
434 | null, |
|
450 | null, | |
435 | null, |
|
451 | null, | |
436 | () => { |
|
452 | () => { | |
@@ -447,7 +463,7 namespace Implab { | |||||
447 | try { |
|
463 | try { | |
448 | var promise = error(e); |
|
464 | var promise = error(e); | |
449 |
|
465 | |||
450 |
promise. |
|
466 | promise.On( | |
451 | medium.Resolve, |
|
467 | medium.Resolve, | |
452 | medium.Reject, |
|
468 | medium.Reject, | |
453 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка |
|
469 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
@@ -486,7 +502,8 namespace Implab { | |||||
486 | resultHandler, |
|
502 | resultHandler, | |
487 | errorHandler, |
|
503 | errorHandler, | |
488 | cancelHandler, |
|
504 | cancelHandler, | |
489 | null |
|
505 | null, | |
|
506 | true | |||
490 | ); |
|
507 | ); | |
491 |
|
508 | |||
492 | return medium; |
|
509 | return medium; | |
@@ -502,7 +519,7 namespace Implab { | |||||
502 |
|
519 | |||
503 | public IPromise<T> Cancelled(Action handler) { |
|
520 | public IPromise<T> Cancelled(Action handler) { | |
504 | var medium = new Promise<T>(this); |
|
521 | var medium = new Promise<T>(this); | |
505 | AddHandler(null, null, handler, medium); |
|
522 | AddHandler(null, null, handler, medium, false); | |
506 | return medium; |
|
523 | return medium; | |
507 | } |
|
524 | } | |
508 |
|
525 | |||
@@ -513,7 +530,9 namespace Implab { | |||||
513 | /// <returns>self</returns> |
|
530 | /// <returns>self</returns> | |
514 | public IPromise<T> Anyway(Action handler) { |
|
531 | public IPromise<T> Anyway(Action handler) { | |
515 | Safe.ArgumentNotNull(handler, "handler"); |
|
532 | Safe.ArgumentNotNull(handler, "handler"); | |
516 |
|
533 | |||
|
534 | var medium = new Promise<T>(this); | |||
|
535 | ||||
517 | AddHandler( |
|
536 | AddHandler( | |
518 | x => handler(), |
|
537 | x => handler(), | |
519 | e => { |
|
538 | e => { | |
@@ -521,9 +540,11 namespace Implab { | |||||
521 | throw new TransientPromiseException(e); |
|
540 | throw new TransientPromiseException(e); | |
522 | }, |
|
541 | }, | |
523 | handler, |
|
542 | handler, | |
524 |
|
|
543 | medium, | |
|
544 | true | |||
525 | ); |
|
545 | ); | |
526 | return this; |
|
546 | ||
|
547 | return medium; | |||
527 | } |
|
548 | } | |
528 |
|
549 | |||
529 | /// <summary> |
|
550 | /// <summary> | |
@@ -579,8 +600,8 namespace Implab { | |||||
579 | return Join(Timeout.Infinite); |
|
600 | return Join(Timeout.Infinite); | |
580 | } |
|
601 | } | |
581 |
|
602 | |||
582 | void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium) { |
|
603 | void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium, bool inc) { | |
583 | if (success != null || error != null) |
|
604 | if (inc) | |
584 | Interlocked.Increment(ref m_childrenCount); |
|
605 | Interlocked.Increment(ref m_childrenCount); | |
585 |
|
606 | |||
586 | var handler = new HandlerDescriptor { |
|
607 | var handler = new HandlerDescriptor { | |
@@ -784,39 +805,39 namespace Implab { | |||||
784 | } |
|
805 | } | |
785 |
|
806 | |||
786 | IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { |
|
807 | IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { | |
787 |
|
|
808 | Safe.ArgumentNotNull(chained, "chained"); | |
788 |
|
809 | |||
789 | var medium = new Promise<object>(this); |
|
810 | var medium = new Promise<object>(this); | |
790 |
|
811 | |||
791 | Action<T> resultHandler = delegate { |
|
812 | Action<T> resultHandler = delegate { | |
792 |
|
|
813 | if (medium.IsCancelled) | |
793 |
|
|
814 | return; | |
794 |
|
815 | |||
795 |
|
|
816 | var promise = chained(); | |
796 |
|
817 | |||
797 |
|
|
818 | promise.On( | |
798 |
|
|
819 | medium.Resolve, | |
799 |
|
|
820 | medium.Reject, | |
800 |
|
|
821 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
801 |
|
|
822 | ); | |
802 |
|
823 | |||
803 |
|
|
824 | // notify chained operation that it's not needed anymore | |
804 |
|
|
825 | // порядок вызова Then, Cancelled важен, поскольку от этого | |
805 |
|
|
826 | // зависит IsExclusive | |
806 |
|
|
827 | medium.Cancelled(() => { | |
807 |
|
|
828 | if (promise.IsExclusive) | |
808 |
|
|
829 | promise.Cancel(); | |
809 |
|
|
830 | }); | |
810 |
|
|
831 | }; | |
811 |
|
832 | |||
812 | Func<Exception,T> errorHandler; |
|
833 | Func<Exception,T> errorHandler; | |
813 |
|
834 | |||
814 |
|
|
835 | if (error != null) | |
815 |
|
|
836 | errorHandler = delegate(Exception e) { | |
816 | try { |
|
837 | try { | |
817 | var promise = error(e); |
|
838 | var promise = error(e); | |
818 |
|
839 | |||
819 |
promise. |
|
840 | promise.On( | |
820 | medium.Resolve, |
|
841 | medium.Resolve, | |
821 | medium.Reject, |
|
842 | medium.Reject, | |
822 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка |
|
843 | () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
@@ -834,50 +855,53 namespace Implab { | |||||
834 | } |
|
855 | } | |
835 | return default(T); |
|
856 | return default(T); | |
836 | }; |
|
857 | }; | |
837 |
|
|
858 | else | |
838 |
|
|
859 | errorHandler = err => { | |
839 | medium.Reject(err); |
|
860 | medium.Reject(err); | |
840 | return default(T); |
|
861 | return default(T); | |
841 | }; |
|
862 | }; | |
842 |
|
863 | |||
843 |
|
864 | |||
844 |
|
|
865 | Action cancelHandler; | |
845 |
|
|
866 | if (cancel != null) | |
846 |
|
|
867 | cancelHandler = () => { | |
847 | if (cancel != null) |
|
868 | if (cancel != null) | |
848 | cancel(); |
|
869 | cancel(); | |
849 | medium.Cancel(); |
|
870 | medium.Cancel(); | |
850 | }; |
|
871 | }; | |
851 |
|
|
872 | else | |
852 |
|
|
873 | cancelHandler = medium.Cancel; | |
853 |
|
874 | |||
854 |
|
|
875 | AddHandler( | |
855 |
|
|
876 | resultHandler, | |
856 |
|
|
877 | errorHandler, | |
857 |
|
|
878 | cancelHandler, | |
858 |
|
|
879 | null, | |
859 |
|
|
880 | true | |
|
881 | ); | |||
860 |
|
882 | |||
861 |
|
|
883 | return medium; | |
862 | } |
|
884 | } | |
|
885 | ||||
863 | IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) { |
|
886 | IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) { | |
864 | return ChainNoResult(chained, error, null); |
|
887 | return ChainNoResult(chained, error, null); | |
865 | } |
|
888 | } | |
|
889 | ||||
866 | IPromise IPromise.Chain(Func<IPromise> chained) { |
|
890 | IPromise IPromise.Chain(Func<IPromise> chained) { | |
867 | return ChainNoResult(chained, null, null); |
|
891 | return ChainNoResult(chained, null, null); | |
868 |
} |
|
892 | } | |
869 |
|
893 | |||
870 |
|
894 | |||
871 |
void IPromise. |
|
895 | void IPromise.On(Action success, Action<Exception> error, Action cancel) { | |
872 |
|
|
896 | On(x => success(), error, cancel); | |
873 | } |
|
897 | } | |
874 |
|
898 | |||
875 |
void IPromise. |
|
899 | void IPromise.On(Action success, Action<Exception> error) { | |
876 |
|
|
900 | On(x => success(), error, null); | |
877 | } |
|
901 | } | |
878 |
|
902 | |||
879 |
void IPromise. |
|
903 | void IPromise.On(Action success) { | |
880 |
|
|
904 | On(x => success(), null, null); | |
881 | } |
|
905 | } | |
882 |
|
906 | |||
883 | IPromise IPromise.Error(Action<Exception> error) { |
|
907 | IPromise IPromise.Error(Action<Exception> error) { |
@@ -14,7 +14,7 namespace Implab { | |||||
14 |
|
14 | |||
15 | var p = new SyncContextPromise<T>(context, that); |
|
15 | var p = new SyncContextPromise<T>(context, that); | |
16 |
|
16 | |||
17 |
that. |
|
17 | that.On( | |
18 | p.Resolve, |
|
18 | p.Resolve, | |
19 | p.Reject, |
|
19 | p.Reject, | |
20 | p.Cancel |
|
20 | p.Cancel | |
@@ -28,7 +28,7 namespace Implab { | |||||
28 |
|
28 | |||
29 | var p = new SyncContextPromise<T>(context, that); |
|
29 | var p = new SyncContextPromise<T>(context, that); | |
30 |
|
30 | |||
31 |
that. |
|
31 | that.On( | |
32 | p.Resolve, |
|
32 | p.Resolve, | |
33 | p.Reject, |
|
33 | p.Reject, | |
34 | p.Cancel |
|
34 | p.Cancel | |
@@ -49,7 +49,7 namespace Implab { | |||||
49 | Safe.ArgumentNotNull(that, "that"); |
|
49 | Safe.ArgumentNotNull(that, "that"); | |
50 | Safe.ArgumentNotNull(head, "head"); |
|
50 | Safe.ArgumentNotNull(head, "head"); | |
51 |
|
51 | |||
52 |
that. |
|
52 | that.On(null,null,() => head.On(cleanup)); | |
53 |
|
53 | |||
54 | return that; |
|
54 | return that; | |
55 | } |
|
55 | } | |
@@ -72,7 +72,7 namespace Implab { | |||||
72 | Safe.ArgumentNotNull(that, "that"); |
|
72 | Safe.ArgumentNotNull(that, "that"); | |
73 | var tcs = new TaskCompletionSource<T>(); |
|
73 | var tcs = new TaskCompletionSource<T>(); | |
74 |
|
74 | |||
75 |
that. |
|
75 | that.On(tcs.SetResult, tcs.SetException, tcs.SetCanceled); | |
76 |
|
76 | |||
77 | return tcs.Task; |
|
77 | return tcs.Task; | |
78 | } |
|
78 | } |
@@ -12,7 +12,7 namespace MonoPlay { | |||||
12 | throw new ArgumentNullException("args"); |
|
12 | throw new ArgumentNullException("args"); | |
13 |
|
13 | |||
14 | var q1 = new MTQueue<int>(); |
|
14 | var q1 = new MTQueue<int>(); | |
15 |
var q2 = new |
|
15 | var q2 = new Queue<int>(); | |
16 |
|
16 | |||
17 | const int count = 10000000; |
|
17 | const int count = 10000000; | |
18 |
|
18 | |||
@@ -32,7 +32,7 namespace MonoPlay { | |||||
32 | t2 = Environment.TickCount; |
|
32 | t2 = Environment.TickCount; | |
33 | Console.WriteLine("LinkedList: {0} ms", t2 - t1); |
|
33 | Console.WriteLine("LinkedList: {0} ms", t2 - t1); | |
34 |
|
34 | |||
35 |
q2 = new |
|
35 | q2 = new Queue<int>(); | |
36 |
|
36 | |||
37 | t1 = Environment.TickCount; |
|
37 | t1 = Environment.TickCount; | |
38 |
|
38 |
General Comments 0
You need to be logged in to leave comments.
Login now