annotate Implab/PromiseExtensions.cs @ 209:a867536c68fc v2

Bound promise to CancellationToken Added new states to ExecutionSate enum. Added Safe.Guard() method to handle cleanup of the result of the promise
author cin
date Wed, 16 Nov 2016 03:06:08 +0300
parents 7d07503621fe
children 5cb4826c2c2a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
1 using System.Threading;
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
2 using System;
109
1b7ebcc52e5a minor fixes
cin
parents: 104
diff changeset
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
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
7 namespace Implab {
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
8 public static class PromiseExtensions {
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
9 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
10 Safe.ArgumentNotNull(that, "that");
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
11 var context = SynchronizationContext.Current;
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
12 if (context == null)
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
13 return that;
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
14
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
15 var p = new SyncContextPromise<T>(context);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
16 p.CancellationRequested(that.Cancel);
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
17
104
5f10d54b45df renamed Promise.Last -> Promise.On
cin
parents: 101
diff changeset
18 that.On(
76
c761fc982e1d Refactoring of the IPromise<T> interface
cin
parents: 75
diff changeset
19 p.Resolve,
c761fc982e1d Refactoring of the IPromise<T> interface
cin
parents: 75
diff changeset
20 p.Reject,
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
21 p.CancelOperation
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
22 );
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
23 return p;
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
24 }
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
25
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
26 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
27 Safe.ArgumentNotNull(that, "that");
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
28 Safe.ArgumentNotNull(context, "context");
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
29
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
30 var p = new SyncContextPromise<T>(context);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
31 p.CancellationRequested(that.Cancel);
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
32
104
5f10d54b45df renamed Promise.Last -> Promise.On
cin
parents: 101
diff changeset
33 that.On(
76
c761fc982e1d Refactoring of the IPromise<T> interface
cin
parents: 75
diff changeset
34 p.Resolve,
c761fc982e1d Refactoring of the IPromise<T> interface
cin
parents: 75
diff changeset
35 p.Reject,
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
36 p.CancelOperation
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
37 );
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
38 return p;
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
39 }
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
40
101
279e226dffdd code cleanup
cin
parents: 76
diff changeset
41 /// <summary>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
42 /// Ensures the dispatched.
279e226dffdd code cleanup
cin
parents: 76
diff changeset
43 /// </summary>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
44 /// <returns>The dispatched.</returns>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
45 /// <param name="that">That.</param>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
46 /// <param name="head">Head.</param>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
47 /// <param name="cleanup">Cleanup.</param>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
48 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
279e226dffdd code cleanup
cin
parents: 76
diff changeset
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
279e226dffdd code cleanup
cin
parents: 76
diff changeset
51 Safe.ArgumentNotNull(that, "that");
279e226dffdd code cleanup
cin
parents: 76
diff changeset
52 Safe.ArgumentNotNull(head, "head");
279e226dffdd code cleanup
cin
parents: 76
diff changeset
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
279e226dffdd code cleanup
cin
parents: 76
diff changeset
55
279e226dffdd code cleanup
cin
parents: 76
diff changeset
56 return that;
279e226dffdd code cleanup
cin
parents: 76
diff changeset
57 }
279e226dffdd code cleanup
cin
parents: 76
diff changeset
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
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
85 Safe.ArgumentNotNull(that, "that");
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
86 Safe.ArgumentNotNull(callback, "callback");
109
1b7ebcc52e5a minor fixes
cin
parents: 104
diff changeset
87 var op = TraceContext.Instance.CurrentOperation;
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
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
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
90 try {
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
91 that.Resolve(callback(ar));
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
92 } catch (Exception err) {
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
93 that.Reject(err);
109
1b7ebcc52e5a minor fixes
cin
parents: 104
diff changeset
94 } finally {
1b7ebcc52e5a minor fixes
cin
parents: 104
diff changeset
95 TraceContext.Instance.Leave();
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
96 }
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
97 };
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
98 }
110
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
99
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
100 static void CancelByTimeoutCallback(object cookie) {
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
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
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
105 /// Cancells promise after the specified timeout is elapsed.
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
106 /// </summary>
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
107 /// <param name="that">The promise to cancel on timeout.</param>
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
108 /// <param name="milliseconds">The timeout in milliseconds.</param>
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
109 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
110 public static TPromise Timeout<TPromise>(this TPromise that, int milliseconds) where TPromise : IPromise {
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
111 Safe.ArgumentNotNull(that, "that");
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
112 var timer = new Timer(CancelByTimeoutCallback, that, milliseconds, -1);
110
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
113 that.On(timer.Dispose, PromiseEventType.All);
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
114 return that;
1a8426e6e895 added promise timeout helper
cin
parents: 109
diff changeset
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) {
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
123 return PromiseAll(that, null);
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
124 }
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
125
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
126 public static IPromise<T[]> PromiseAll<T>(this IEnumerable<IPromise<T>> that, Action<T> cleanup) {
205
8200ab154c8a Added ResetState to RunnableComponent to reset in case of failure
cin
parents: 185
diff changeset
127 Safe.ArgumentNotNull(that, "that");
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
128 return PromiseAll(that.ToList(), cleanup);
205
8200ab154c8a Added ResetState to RunnableComponent to reset in case of failure
cin
parents: 185
diff changeset
129 }
8200ab154c8a Added ResetState to RunnableComponent to reset in case of failure
cin
parents: 185
diff changeset
130
8200ab154c8a Added ResetState to RunnableComponent to reset in case of failure
cin
parents: 185
diff changeset
131 public static IPromise PromiseAll(this ICollection<IPromise> that) {
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
132 Safe.ArgumentNotNull(that, "that");
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
133
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
134 int count = that.Count;
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
135 int errors = 0;
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
136 var medium = new Promise();
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
137
136
e9e7940c7d98 shared locks + tests
cin
parents: 124
diff changeset
138 if (count == 0) {
e9e7940c7d98 shared locks + tests
cin
parents: 124
diff changeset
139 medium.Resolve();
e9e7940c7d98 shared locks + tests
cin
parents: 124
diff changeset
140 return medium;
e9e7940c7d98 shared locks + tests
cin
parents: 124
diff changeset
141 }
e9e7940c7d98 shared locks + tests
cin
parents: 124
diff changeset
142
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
143 medium.On(() => {
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
144 foreach (var p2 in that)
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
145 p2.Cancel();
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
146 }, PromiseEventType.ErrorOrCancel);
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
147
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
148 foreach (var p in that)
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
149 p.On(
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
150 () => {
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
151 if (Interlocked.Decrement(ref count) == 0)
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
152 medium.Resolve();
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
153 },
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
154 error => {
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
155 if (Interlocked.Increment(ref errors) == 1)
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
156 medium.Reject(
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
157 new Exception("The dependency promise is failed", error)
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
158 );
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
159 },
138
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 136
diff changeset
160 reason => {
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
161 if (Interlocked.Increment(ref errors) == 1)
138
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 136
diff changeset
162 medium.Cancel(
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
163 new Exception("The dependency promise is cancelled")
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
164 );
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
165 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
166 );
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
167
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
168 return medium;
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 110
diff changeset
169 }
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
170
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
171 public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that) {
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
172 return PromiseAll(that, null);
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
173 }
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
174
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
175 /// <summary>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
176 /// Creates a new promise which will be satisfied when all promises are satisfied.
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
177 /// </summary>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
178 /// <typeparam name="T"></typeparam>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
179 /// <param name="that"></param>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
180 /// <param name="cleanup">A callback used to cleanup already resolved promises in case of an error</param>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
181 /// <returns></returns>
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
182 public static IPromise<T[]> PromiseAll<T>(this ICollection<IPromise<T>> that, Action<T> cleanup) {
209
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
183 Safe.ArgumentNotNull(that, "that");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
184
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
185 int count = that.Count;
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
186
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
187 if (count == 0)
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
188 return Promise<T[]>.FromResult(new T[0]);
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
189
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
190 int errors = 0;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
191 var medium = new Promise<T[]>();
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
192 var results = new T[that.Count];
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
193
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
194 medium.On(() => {
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
195 foreach (var p2 in that) {
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
196 p2.Cancel();
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
197 if (cleanup != null)
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
198 p2.On(cleanup);
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
199 }
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
200 }, PromiseEventType.ErrorOrCancel);
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
201
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
202 int i = 0;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
203 foreach (var p in that) {
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
204 var idx = i;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
205 p.On(
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
206 x => {
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
207 results[idx] = x;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
208 if (Interlocked.Decrement(ref count) == 0)
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
209 medium.Resolve(results);
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
210 },
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
211 error => {
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
212 if (Interlocked.Increment(ref errors) == 1)
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
213 medium.Reject(
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
214 new Exception("The dependency promise is failed", error)
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
215 );
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
216 },
138
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 136
diff changeset
217 reason => {
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
218 if (Interlocked.Increment(ref errors) == 1)
138
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 136
diff changeset
219 medium.Cancel(
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 136
diff changeset
220 new Exception("The dependency promise is cancelled", reason)
124
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
221 );
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
222 }
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
223 );
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
224 i++;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
225 }
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
226
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
227 return medium;
a336cb13c6a9 major update, added Drain mathod to AsyncQueue class
cin
parents: 119
diff changeset
228 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
229
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
230 public static IPromise Then(this IPromise that, Action success, Action<Exception> error, Action<Exception> cancel) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
231 Safe.ArgumentNotNull(that, "that");
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
232
149
eb793fbbe4ea fixed promises cancellation
cin
parents: 145
diff changeset
233 var d = new ActionTask(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
234 that.On(d.Resolve, d.Reject, d.CancelOperation);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
235 d.CancellationRequested(that.Cancel);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
236 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
237 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
238
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
239 public static IPromise Then(this IPromise that, Action success, Action<Exception> error) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
240 return Then(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
241 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
242
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
243 public static IPromise Then(this IPromise that, Action success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
244 return Then(that, success, null, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
245 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
246
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
247 public static IPromise<T> Then<T>(this IPromise that, Func<T> success, Func<Exception, T> error, Func<Exception, T> cancel) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
248 Safe.ArgumentNotNull(that, "that");
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
249
149
eb793fbbe4ea fixed promises cancellation
cin
parents: 145
diff changeset
250 var d = new FuncTask<T>(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
251 that.On(d.Resolve, d.Reject, d.CancelOperation);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
252 d.CancellationRequested(that.Cancel);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
253 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
254 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
255
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
256 public static IPromise<T> Then<T>(this IPromise that, Func<T> success, Func<Exception, T> error) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
257 return Then(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
258 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
259
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
260 public static IPromise<T> Then<T>(this IPromise that, Func<T> success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
261 return Then(that, success, null, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
262 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
263
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
264 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success, Func<Exception, T2> error, Func<Exception, T2> cancel) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
265 Safe.ArgumentNotNull(that, "that");
209
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
266 Safe.ArgumentNotNull(success, "success");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
267
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
268 var d = new FuncTask<T, T2>(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
269 that.On(d.Resolve, d.Reject, d.CancelOperation);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
270 d.CancellationRequested(that.Cancel);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
271 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
272 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
273
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
274 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
275 Safe.ArgumentNotNull(that, "that");
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
276 var d = new FuncTask<T, T>(
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
277 x => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
278 success(x);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
279 return x;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
280 },
209
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
281 error,
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
282 cancel,
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
283 false
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
284 );
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
285 that.On(d.Resolve, d.Reject, d.CancelOperation);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
286 d.CancellationRequested(that.Cancel);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
287 return d;
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
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
290 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
291 return Then(that, success, error, null);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
292 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
293
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
294 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
295 return Then(that, success, null, null);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
296 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
297
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
298 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success, Func<Exception, T2> error) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
299 return Then(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
300 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
301
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
302 public static IPromise<T2> Then<T, T2>(this IPromise<T> that, Func<T, T2> success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
303 return Then(that, success, null, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
304 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
305
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
306 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
307 Func<Exception, T> errorOrCancel;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
308 if (handler != null)
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
309 errorOrCancel = e => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
310 handler();
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
311 throw new PromiseTransientException(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
312 };
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
313 else
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
314 errorOrCancel = null;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
315
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
316 return Then(
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
317 that,
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
318 x => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
319 handler();
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
320 return x;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
321 },
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
322 errorOrCancel,
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
323 errorOrCancel);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
324 }
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 public static IPromise Always(this IPromise that, Action handler) {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
327 Action<Exception> errorOrCancel;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
328 if (handler != null)
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
329 errorOrCancel = e => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
330 handler();
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
331 throw new PromiseTransientException(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
332 };
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
333 else
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
334 errorOrCancel = null;
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 return Then(
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
337 that,
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
338 handler,
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
339 errorOrCancel,
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
340 errorOrCancel);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
341 }
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 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
344 Action<Exception> errorOrCancel;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
345 if (handler != null)
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
346 errorOrCancel = e => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
347 handler(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
348 throw new PromiseTransientException(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
349 };
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
350 else
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
351 errorOrCancel = null;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
352
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
353 return Then(that, null, errorOrCancel, handleCancellation ? errorOrCancel : null);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
354 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
355
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
356 public static IPromise Error(this IPromise that, Action<Exception> handler) {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
357 return Error(that, handler, false);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
358 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
359
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
360 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
361 Func<Exception, T> errorOrCancel;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
362 if (handler != null)
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
363 errorOrCancel = e => {
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
364 handler(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
365 throw new PromiseTransientException(e);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
366 };
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
367 else
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
368 errorOrCancel = null;
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
369
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
370 return Then(that, null, errorOrCancel, handleCancellation ? errorOrCancel : null);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
371 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
372
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
373 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
374 return Error(that, handler, false);
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
375 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
376
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
377 #region chain traits
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
378 public static IPromise Chain(this IPromise that, Func<IPromise> success, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel) {
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
379 Safe.ArgumentNotNull(that, "that");
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
380
149
eb793fbbe4ea fixed promises cancellation
cin
parents: 145
diff changeset
381 var d = new ActionChainTask(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
382 that.On(d.Resolve, d.Reject, d.CancelOperation);
185
822aab37b107 runnable component, work in progress
cin
parents: 151
diff changeset
383 d.CancellationRequested(that.Cancel);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
384 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
385 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
386
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
387 public static IPromise Chain(this IPromise that, Func<IPromise> success, Func<Exception, IPromise> error) {
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
388 return Chain(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
389 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
390
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
391 public static IPromise Chain(this IPromise that, Func<IPromise> success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
392 return Chain(that, success, null, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
393 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
394
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
395 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success, Func<Exception, IPromise<T>> error, Func<Exception, IPromise<T>> cancel) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
396 Safe.ArgumentNotNull(that, "that");
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
397
149
eb793fbbe4ea fixed promises cancellation
cin
parents: 145
diff changeset
398 var d = new FuncChainTask<T>(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
399 that.On(d.Resolve, d.Reject, d.CancelOperation);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
400 if (success != null)
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
401 d.CancellationRequested(that.Cancel);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
402 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
403 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
404
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
405 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success, Func<Exception, IPromise<T>> error) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
406 return Chain(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
407 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
408
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
409 public static IPromise<T> Chain<T>(this IPromise that, Func<IPromise<T>> success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
410 return Chain(that, success, null, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
411 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
412
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
413 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) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
414 Safe.ArgumentNotNull(that, "that");
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
415 var d = new FuncChainTask<T, T2>(success, error, cancel, false);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
416 that.On(d.Resolve, d.Reject, d.CancelOperation);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
417 if (success != null)
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
418 d.CancellationRequested(that.Cancel);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
419 return d;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
420 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
421
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
422 public static IPromise<T2> Chain<T, T2>(this IPromise<T> that, Func<T, IPromise<T2>> success, Func<Exception, IPromise<T2>> error) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
423 return Chain(that, success, error, null);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
424 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
425
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
426 public static IPromise<T2> Chain<T, T2>(this IPromise<T> that, Func<T, IPromise<T2>> success) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
427 return Chain(that, success, null, null);
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
428 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
429
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 138
diff changeset
430 #endregion
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
431
209
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
432 public static IPromise<T2> Guard<T, T2>(this IPromise<T> that, Func<IPromise<T>, IPromise<T2>> continuation, Action<T> cleanup) {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
433 Safe.ArgumentNotNull(that, "that");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
434 Safe.ArgumentNotNull(continuation, "continuation");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
435 return continuation(that).Error((err) => {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
436 that.On(cleanup);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
437 }, true);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
438 }
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
439
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
440 #if NET_4_5
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
441
151
ec91a6dfa5b3 Added support for 'await' operator to promises
cin
parents: 149
diff changeset
442 public static PromiseAwaiter<T> GetAwaiter<T>(this IPromise<T> that) {
75
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
443 Safe.ArgumentNotNull(that, "that");
4439140706d0 major refactoring, added tasks support
cin
parents: 72
diff changeset
444
151
ec91a6dfa5b3 Added support for 'await' operator to promises
cin
parents: 149
diff changeset
445 return new PromiseAwaiter<T>(that);
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
446 }
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
447
208
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
448 public static PromiseAwaiter GetAwaiter(this IPromise that) {
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
449 Safe.ArgumentNotNull(that, "that");
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
450
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
451 return new PromiseAwaiter(that);
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
452 }
7d07503621fe RunnableComponent.Dispose(bool,Exception) changed to standart Dispose(bool)
cin
parents: 207
diff changeset
453
209
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
454 public static IPromise BoundCancellationToken(this IPromise that, CancellationToken ct) {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
455 Safe.ArgumentNotNull(that, "that");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
456 ct.Register(that.Cancel);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
457 return that.Then(null, null, (err) => {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
458 ct.ThrowIfCancellationRequested();
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
459 throw new PromiseTransientException(err);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
460 });
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
461 }
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
462
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
463 public static IPromise<T> BoundCancellationToken<T>(this IPromise<T> that, CancellationToken ct) {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
464 Safe.ArgumentNotNull(that, "that");
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
465 ct.Register(that.Cancel);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
466 return that.Then(null, null, (err) => {
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
467 ct.ThrowIfCancellationRequested();
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
468 throw new PromiseTransientException(err);
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
469 });
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
470 }
a867536c68fc Bound promise to CancellationToken
cin
parents: 208
diff changeset
471
207
558f34b2fb50 added Safe.DispatchEvent() a legacy equivalent for '?.Invoke()'
cin
parents: 205
diff changeset
472 #endif
72
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
473 }
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
474 }
d67b95eddaf4 promises refactoring
cin
parents:
diff changeset
475