##// END OF EJS Templates
minor fixes and optimizations
cin -
r107:f5220e5472ef v2
parent child
Show More
@@ -1,894 +1,954
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Reflection;
4 4 using System.Threading;
5 5 using Implab.Parallels;
6 6
7 7 namespace Implab {
8 8
9 9 /// <summary>
10 10 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
11 11 /// </summary>
12 12 /// <typeparam name="T">Π’ΠΈΠΏ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°</typeparam>
13 13 /// <remarks>
14 14 /// <para>БСрвис ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π΄Π°Π΅Ρ‚ ΠΎΠ±Π΅Ρ‰Π°ΠΈΠ½ΠΈΠ΅ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ,
15 15 /// ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ² Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ряд ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎ для получСния
16 16 /// событий выполнСния обСщания, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ прСдоставлСнии Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².</para>
17 17 /// <para>
18 18 /// ΠžΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ с ошибкой. Для подписки Π½Π°
19 19 /// Π΄Π°Π½Π½Ρ‹Π΅ события ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Then</c>.
20 20 /// </para>
21 21 /// <para>
22 22 /// БСрвис, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ошибкой),
23 23 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Resolve</c> Π»ΠΈΠ±ΠΎ <c>Reject</c> для оповСщСния ΠΊΠ»ΠΈΠ΅Ρ‚Π½Π° ΠΎ
24 24 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ обСщания.
25 25 /// </para>
26 26 /// <para>
27 27 /// Если сСрвСр успСл Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° Π½Π΅Π³ΠΎ подписался,
28 28 /// Ρ‚ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ подписки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠ΅ события Π² синхронном
29 29 /// Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ Π² любом случаС. Π˜Π½Π°Ρ‡Π΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²
30 30 /// список Π² порядкС подписания ΠΈ Π² этом ΠΆΠ΅ порядкС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ
31 31 /// обСщания.
32 32 /// </para>
33 33 /// <para>
34 34 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обСщания ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
35 35 /// связанныС асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ обСщания. Для этого слСдуСт
36 36 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ <c>Then</c>.
37 37 /// </para>
38 38 /// <para>
39 39 /// Π’Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ <c>Resolve</c> ΠΈ <c>Reject</c> Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
40 40 /// Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΎΡ€ обСщания ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ противорСчия.
41 41 /// </para>
42 42 /// </remarks>
43 43 public class Promise<T> : IPromise<T> {
44 44
45 45 protected abstract class AbstractHandler : MTCustomQueueNode<AbstractHandler> {
46 46 public abstract void Resolve(T result);
47 47 public abstract void Reject(Exception error);
48 48 public abstract void Cancel();
49 49 }
50 50
51 protected class HandlerDescriptor<T2> : AbstractHandler {
51 protected class RemapDescriptor<T2> : AbstractHandler {
52 52
53 53 readonly Func<T,T2> m_resultHandler;
54 54 readonly Func<Exception,T2> m_errorHandler;
55 55 readonly Action m_cancellHandler;
56 56 readonly Promise<T2> m_medium;
57 57
58 public HandlerDescriptor(Func<T,T2> resultHandler, Func<Exception,T2> errorHandler, Action cancelHandler, Promise<T2> medium) {
58 public RemapDescriptor(Func<T,T2> resultHandler, Func<Exception,T2> errorHandler, Action cancelHandler, Promise<T2> medium) {
59 59 m_resultHandler = resultHandler;
60 60 m_errorHandler = errorHandler;
61 61 m_cancellHandler = cancelHandler;
62 62 m_medium = medium;
63 63 }
64 64
65 65 public override void Resolve(T result) {
66 66 if (m_resultHandler != null) {
67 67 try {
68 68 if (m_medium != null)
69 69 m_medium.Resolve(m_resultHandler(result));
70 70 else
71 71 m_resultHandler(result);
72 72 } catch (Exception e) {
73 73 Reject(e);
74 74 }
75 75 } else if(m_medium != null)
76 76 m_medium.Resolve(default(T2));
77 77 }
78 78
79 79 public override void Reject(Exception error) {
80 80 if (m_errorHandler != null) {
81 81 try {
82 82 var res = m_errorHandler(error);
83 83 if (m_medium != null)
84 84 m_medium.Resolve(res);
85 /*} catch (TransientPromiseException err2) {
86 if (medium != null)
87 medium.Reject(err2.InnerException);*/
85 } catch (Exception err2) {
86 if (m_medium != null)
87 m_medium.Reject(err2);
88 }
89 } else if (m_medium != null)
90 m_medium.Reject(error);
91 }
92
93 public override void Cancel() {
94 if (m_cancellHandler != null) {
95 try {
96 m_cancellHandler();
97 } catch (Exception err) {
98 Reject(err);
99 return;
100 }
101 }
102 if (m_medium != null)
103 m_medium.Cancel();
104 }
105 }
106
107 protected class HandlerDescriptor : AbstractHandler {
108
109 readonly Action<T> m_resultHandler;
110 readonly Action<Exception> m_errorHandler;
111 readonly Action m_cancellHandler;
112 readonly Promise<T> m_medium;
113
114 public HandlerDescriptor(Action<T> resultHandler, Action<Exception> errorHandler, Action cancelHandler, Promise<T> medium) {
115 m_resultHandler = resultHandler;
116 m_errorHandler = errorHandler;
117 m_cancellHandler = cancelHandler;
118 m_medium = medium;
119 }
120
121 public override void Resolve(T result) {
122 if (m_resultHandler != null) {
123 try {
124 m_resultHandler(result);
125 } catch (Exception e) {
126 Reject(e);
127 return;
128 }
129 }
130 if(m_medium != null)
131 m_medium.Resolve(result);
132 }
133
134 public override void Reject(Exception error) {
135 if (m_errorHandler != null) {
136 try {
137 m_errorHandler(error);
138 if (m_medium != null)
139 m_medium.Resolve(default(T));
88 140 } catch (Exception err2) {
89 141 if (m_medium != null)
90 142 m_medium.Reject(err2);
91 143 }
92 144 } else if (m_medium != null)
93 145 m_medium.Reject(error);
94 146 }
95 147
96 148 public override void Cancel() {
97 149 if (m_cancellHandler != null) {
98 150 try {
99 151 m_cancellHandler();
100 152 } catch (Exception err) {
101 153 Reject(err);
102 154 return;
103 155 }
104 156 }
105 157 if (m_medium != null)
106 158 m_medium.Cancel();
107 159 }
108 160 }
109 161
110 162 const int UNRESOLVED_SATE = 0;
111 163 const int TRANSITIONAL_STATE = 1;
112 164 const int SUCCEEDED_STATE = 2;
113 165 const int REJECTED_STATE = 3;
114 166 const int CANCELLED_STATE = 4;
115 167
116 168 int m_childrenCount;
117 169 int m_state;
118 170 T m_result;
119 171 Exception m_error;
120 172
121 173 readonly MTCustomQueue<AbstractHandler> m_handlers = new MTCustomQueue<AbstractHandler>();
122 174 //readonly MTQueue<AbstractHandler> m_handlers = new MTQueue<AbstractHandler>();
123 175
124 176 public Promise() {
125 177 }
126 178
127 179 public Promise(IPromise parent) {
128 180 if (parent != null)
129 AddHandler<T>(
181 AddMappers<T>(
130 182 null,
131 183 null,
132 184 () => {
133 185 if (parent.IsExclusive)
134 186 parent.Cancel();
135 187 },
136 188 null,
137 189 false
138 190 );
139 191 }
140 192
141 193 bool BeginTransit() {
142 194 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
143 195 }
144 196
145 197 void CompleteTransit(int state) {
146 198 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
147 199 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
148 200 }
149 201
150 202 void WaitTransition() {
151 203 while (m_state == TRANSITIONAL_STATE) {
152 204 Thread.MemoryBarrier();
153 205 }
154 206 }
155 207
156 208 public bool IsResolved {
157 209 get {
158 210 Thread.MemoryBarrier();
159 211 return m_state > 1;
160 212 }
161 213 }
162 214
163 215 public bool IsCancelled {
164 216 get {
165 217 Thread.MemoryBarrier();
166 218 return m_state == CANCELLED_STATE;
167 219 }
168 220 }
169 221
170 222 public Type PromiseType {
171 223 get { return typeof(T); }
172 224 }
173 225
174 226 /// <summary>
175 227 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ.
176 228 /// </summary>
177 229 /// <param name="result">Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния.</param>
178 230 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
179 231 public void Resolve(T result) {
180 232 if (BeginTransit()) {
181 233 m_result = result;
182 234 CompleteTransit(SUCCEEDED_STATE);
183 235 OnStateChanged();
184 236 } else {
185 237 WaitTransition();
186 238 if (m_state != CANCELLED_STATE)
187 239 throw new InvalidOperationException("The promise is already resolved");
188 240 }
189 241 }
190 242
191 243 /// <summary>
192 244 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
193 245 /// </summary>
194 246 /// <remarks>
195 247 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
196 248 /// </remarks>
197 249 public void Resolve() {
198 250 Resolve(default(T));
199 251 }
200 252
201 253 /// <summary>
202 254 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
203 255 /// </summary>
204 256 /// <remarks>
205 257 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
206 258 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
207 259 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
208 260 /// </remarks>
209 261 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
210 262 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
211 263 public void Reject(Exception error) {
212 264 if (BeginTransit()) {
213 265 m_error = error is TransientPromiseException ? error.InnerException : error;
214 266 CompleteTransit(REJECTED_STATE);
215 267 OnStateChanged();
216 268 } else {
217 269 WaitTransition();
218 270 if (m_state == SUCCEEDED_STATE)
219 271 throw new InvalidOperationException("The promise is already resolved");
220 272 }
221 273 }
222 274
223 275 /// <summary>
224 276 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
225 277 /// </summary>
226 278 /// <remarks>Для опрСдСлСния Π±Ρ‹Π»Π° Π»ΠΈ опСрация ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π° слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свойство <see cref="IsCancelled"/>.</remarks>
227 279 public void Cancel() {
228 280 if (BeginTransit()) {
229 281 CompleteTransit(CANCELLED_STATE);
230 282 OnStateChanged();
231 283 }
232 284 }
233 285
234 286 /// <summary>
235 287 /// ПослСдний ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
236 288 /// </summary>
237 289 /// <param name="success"></param>
238 290 /// <param name="error"></param>
239 291 /// <param name="cancel"></param>
240 292 /// <remarks>
241 293 /// <para>
242 294 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ создаСт связанного с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ обСщания ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для окончания
243 295 /// фсинхронной Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ.
244 296 /// </para>
245 297 /// <para>
246 298 /// Если Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ нСсколько Ρ€Π°Π·, Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, Ρ‚ΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°
247 299 /// Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠΉ <see cref="IsExclusive"/> ΠΈ, ΠΊΠ°ΠΊ слСдствиС, Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ΠΎΡ‚ΠΌΠ΅Π½Π°
248 300 /// всСй Ρ†Π΅ΠΏΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ снизу (с самого послСднСго обСщания).
249 301 /// </para>
250 302 /// </remarks>
251 303 public void On(Action<T> success, Action<Exception> error, Action cancel) {
252 304 if (success == null && error == null && cancel == null)
253 305 return;
254 306
255 AddHandler(
256 success != null ? new Func<T,T>(x => {
257 success(x);
258 return x;
259 }) : null,
260 error != null ? new Func<Exception,T>(e => {
261 error(e);
262 return default(T);
263 }) : null,
264 cancel,
265 null,
266 false
267 );
307 AddHandler(success, error, cancel, null, false);
268 308 }
269 309
270 310 public void On(Action<T> success, Action<Exception> error) {
271 On(success, error, null);
311 AddHandler(success, error, null, null, false);
272 312 }
273 313
274 314 public void On(Action<T> success) {
275 On(success, null, null);
315 AddHandler(success, null, null, null, false);
276 316 }
277 317
278 318 public void On(Action handler, PromiseEventType events) {
279 319 Safe.ArgumentNotNull(handler, "handler");
280 320
281 Func<T,T> success = events.HasFlag(PromiseEventType.Success) ? new Func<T,T>(x => {
282 handler();
283 return x;
284 }) : null;
285 Func<Exception,T> error = events.HasFlag(PromiseEventType.Error) ? new Func<Exception,T>(e => {
286 handler();
287 return default(T);
288 }) : null;
289 Action cancel = events.HasFlag(PromiseEventType.Cancelled) ? handler : null;
290 321
291 AddHandler(success, error, cancel, null, false);
322 AddHandler(
323 events.HasFlag(PromiseEventType.Success) ? new Action<T>(x => handler()) : null,
324 events.HasFlag(PromiseEventType.Error) ? new Action<Exception>( x => handler()) : null,
325 events.HasFlag(PromiseEventType.Cancelled) ? handler : null,
326 null,
327 false
328 );
292 329 }
293 330
294 331 public IPromise Error(Action<Exception> error) {
295 332 if (error == null)
296 333 return this;
297 334
298 335 var medium = new Promise<T>(this);
299 336
300 AddHandler(
337 AddMappers(
301 338 null,
302 339 e => {
303 340 error(e);
304 341 return default(T);
305 342 },
306 343 null,
307 344 medium,
308 345 true
309 346 );
310 347
311 348 return medium;
312 349 }
313 350
314 351 /// <summary>
315 352 /// Handles error and allows to keep the promise.
316 353 /// </summary>
317 354 /// <remarks>
318 355 /// If the specified handler throws an exception, this exception will be used to reject the promise.
319 356 /// </remarks>
320 357 /// <param name="handler">The error handler which returns the result of the promise.</param>
321 358 /// <returns>New promise.</returns>
322 359 public IPromise<T> Error(Func<Exception,T> handler) {
323 360 if (handler == null)
324 361 return this;
325 362
326 363 var medium = new Promise<T>(this);
327 364
328 AddHandler(null, handler, null, medium, true);
365 AddMappers(null, handler, null, medium, true);
329 366
330 367 return medium;
331 368 }
332 369
333 370 /// <summary>
334 371 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.
335 372 /// </summary>
336 373 /// <typeparam name="TNew">Новый Ρ‚ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.</typeparam>
337 374 /// <param name="mapper">ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.</param>
338 375 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
339 376 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
340 377 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ исходного обСщания.</returns>
341 378 /// <param name = "cancel"></param>
342 379 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error, Action cancel) {
343 380 Safe.ArgumentNotNull(mapper, "mapper");
344 381
345 382 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
346 383 var medium = new Promise<TNew>(this);
347 384
348 AddHandler(
385 AddMappers(
349 386 mapper,
350 387 error,
351 388 cancel,
352 389 medium,
353 390 true
354 391 );
355 392
356 393 return medium;
357 394 }
358 395
359 396 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error) {
360 397 return Then(mapper, error, null);
361 398 }
362 399
363 400 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper) {
364 401 return Then(mapper, null, null);
365 402 }
366 403
367 404 /// <summary>
368 405 /// БцСпляСт нСсколько аснхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Указанная асинхронная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° послС
369 406 /// выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
370 407 /// Π½ΠΎΠ²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
371 408 /// </summary>
372 409 /// <typeparam name="TNew">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</typeparam>
373 410 /// <param name="chained">Асинхронная опСрация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒΡΡ послС выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ.</param>
374 411 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
375 412 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΠ΅Ρ‰ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
376 413 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ аснхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</returns>
377 414 /// <param name = "cancel"></param>
378 415 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error, Action cancel) {
379 416
380 417 Safe.ArgumentNotNull(chained, "chained");
381 418
382 419 // ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ связывания Π΅Ρ‰Π΅ Π½Π΅ Π½Π°Ρ‡Π°Ρ‚Π° асинхронная опСрация, поэтому Π½ΡƒΠΆΠ½ΠΎ
383 420 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π²Ρ‹Π·ΡΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
384 421 // ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ асинхронная опСрация, ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ посрСднику, Ρ‡Ρ‚ΠΎΠ±Ρ‹
385 422 // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
386 423 var medium = new Promise<TNew>(this);
387 424
388 425 Func<T,T> resultHandler = delegate(T result) {
389 426 if (medium.IsCancelled)
390 427 return default(T);
391 428
392 429 var promise = chained(result);
393 430
394 431 promise.On(
395 432 medium.Resolve,
396 433 medium.Reject,
397 434 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
398 435 );
399 436
400 437 // notify chained operation that it's not needed anymore
401 438 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
402 439 // зависит IsExclusive
403 440 medium.On(
404 441 null,
405 442 null,
406 443 () => {
407 444 if (promise.IsExclusive)
408 445 promise.Cancel();
409 446 }
410 447 );
411 448
412 449 return default(T);
413 450 };
414 451
415 452 Func<Exception,T> errorHandler;
416 453
417 454 if (error != null)
418 455 errorHandler = delegate(Exception e) {
419 456 try {
420 457 var promise = error(e);
421 458
422 459 promise.On(
423 460 medium.Resolve,
424 461 medium.Reject,
425 462 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
426 463 );
427 464
428 465 // notify chained operation that it's not needed anymore
429 466 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
430 467 // зависит IsExclusive
431 468 medium.Cancelled(() => {
432 469 if (promise.IsExclusive)
433 470 promise.Cancel();
434 471 });
435 472 } catch (Exception e2) {
436 473 medium.Reject(e2);
437 474 }
438 475 return default(T);
439 476 };
440 477 else
441 478 errorHandler = err => {
442 479 medium.Reject(err);
443 480 return default(T);
444 481 };
445 482
446 483
447 484 Action cancelHandler;
448 485 if (cancel != null)
449 486 cancelHandler = () => {
450 487 if (cancel != null)
451 488 cancel();
452 489 medium.Cancel();
453 490 };
454 491 else
455 492 cancelHandler = medium.Cancel;
456 493
457 AddHandler(
494 AddMappers(
458 495 resultHandler,
459 496 errorHandler,
460 497 cancelHandler,
461 498 null,
462 499 true
463 500 );
464 501
465 502 return medium;
466 503 }
467 504
468 505 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error) {
469 506 return Chain(chained, error, null);
470 507 }
471 508
472 509 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained) {
473 510 return Chain(chained, null, null);
474 511 }
475 512
476 513 public IPromise<T> Cancelled(Action handler) {
477 514 var medium = new Promise<T>(this);
478 515 AddHandler(null, null, handler, medium, false);
479 516 return medium;
480 517 }
481 518
482 519 /// <summary>
483 520 /// Adds the specified handler for all cases (success, error, cancel)
484 521 /// </summary>
485 522 /// <param name="handler">The handler that will be called anyway</param>
486 523 /// <returns>self</returns>
487 524 public IPromise<T> Anyway(Action handler) {
488 525 Safe.ArgumentNotNull(handler, "handler");
489 526
490 527 var medium = new Promise<T>(this);
491 528
492 529 AddHandler(
493 x => {
494 handler();
495 return x;
496 },
530 x => handler(),
497 531 e => {
498 532 handler();
499 533 throw new TransientPromiseException(e);
500 534 },
501 535 handler,
502 536 medium,
503 537 true
504 538 );
505 539
506 540 return medium;
507 541 }
508 542
509 543 /// <summary>
510 544 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ
511 545 /// </summary>
512 546 /// <typeparam name="T2"></typeparam>
513 547 /// <returns></returns>
514 548 public IPromise<T2> Cast<T2>() {
515 549 return Then(x => (T2)(object)x, null);
516 550 }
517 551
518 552 /// <summary>
519 553 /// ДоТидаСтся ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ обСщания ΠΈ Π² случаС успСха, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
520 554 /// Π΅Π³ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС бросаСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
521 555 /// </summary>
522 556 /// <remarks>
523 557 /// <para>
524 558 /// Если ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ обСщания Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ, это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚,
525 559 /// Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² этом Ρ€ΠΎΠ΄Π΅, это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
526 560 /// ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΅Π³ΠΎ Π½Π΅ доТдались, ΠΎΠ΄Π½Π°ΠΊΠΎ всС зарСгистрированныС
527 561 /// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΈ Ρ‚Π°ΠΊ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΈ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹, ΠΊΠΎΠ³Π΄Π°
528 562 /// ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
529 563 /// </para>
530 564 /// <para>
531 565 /// Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΡ‚Π΅Ρ‡ΡŒ
532 566 /// Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΈ
533 567 /// ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ
534 568 /// ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ.
535 569 /// </para>
536 570 /// </remarks>
537 571 /// <param name="timeout">ВрСмя оТидания</param>
538 572 /// <returns>Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния обСщания</returns>
539 573 public T Join(int timeout) {
540 574 var evt = new ManualResetEvent(false);
541 575 Anyway(() => evt.Set());
542 576
543 577 if (!evt.WaitOne(timeout, true))
544 578 throw new TimeoutException();
545 579
546 580 switch (m_state) {
547 581 case SUCCEEDED_STATE:
548 582 return m_result;
549 583 case CANCELLED_STATE:
550 584 throw new OperationCanceledException();
551 585 case REJECTED_STATE:
552 586 throw new TargetInvocationException(m_error);
553 587 default:
554 588 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
555 589 }
556 590 }
557 591
558 592 public T Join() {
559 593 return Join(Timeout.Infinite);
560 594 }
561 595
562 void AddHandler<T2>(Func<T,T2> success, Func<Exception,T2> error, Action cancel, Promise<T2> medium, bool inc) {
596 void AddMappers<T2>(Func<T,T2> success, Func<Exception,T2> error, Action cancel, Promise<T2> medium, bool inc) {
563 597 if (inc)
564 598 Interlocked.Increment(ref m_childrenCount);
565 599
566 AbstractHandler handler = new HandlerDescriptor<T2>(success, error, cancel, medium);
600 AbstractHandler handler = new RemapDescriptor<T2>(success, error, cancel, medium);
601
602 bool queued;
603
604 if (!IsResolved) {
605 m_handlers.Enqueue(handler);
606 queued = true;
607 } else {
608 // the promise is in resolved state, just invoke the handled with minimum overhead
609 queued = false;
610 InvokeHandler(handler);
611 }
612
613 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
614 // if the promise have been resolved while we was adding handler to the queue
615 // we can't guarantee that someone is still processing it
616 // therefore we will fetch a handler from the queue and execute it
617 // note that fetched handler may be not the one that we have added
618 // even we can fetch no handlers at all :)
619 InvokeHandler(handler);
620 }
621
622 void AddHandler(Action<T> success, Action<Exception> error, Action cancel, Promise<T> medium, bool inc) {
623 if (inc)
624 Interlocked.Increment(ref m_childrenCount);
625
626 AbstractHandler handler = new HandlerDescriptor(success, error, cancel, medium);
567 627
568 628 bool queued;
569 629
570 630 if (!IsResolved) {
571 631 m_handlers.Enqueue(handler);
572 632 queued = true;
573 633 } else {
574 634 // the promise is in resolved state, just invoke the handled with minimum overhead
575 635 queued = false;
576 636 InvokeHandler(handler);
577 637 }
578 638
579 639 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
580 640 // if the promise have been resolved while we was adding handler to the queue
581 641 // we can't guarantee that someone is still processing it
582 642 // therefore we will fetch a handler from the queue and execute it
583 643 // note that fetched handler may be not the one that we have added
584 644 // even we can fetch no handlers at all :)
585 645 InvokeHandler(handler);
586 646 }
587 647
588 648 protected virtual void InvokeHandler(AbstractHandler handler) {
589 649 switch (m_state) {
590 650 case SUCCEEDED_STATE:
591 651 handler.Resolve(m_result);
592 652 break;
593 653 case REJECTED_STATE:
594 654 handler.Reject(m_error);
595 655 break;
596 656 case CANCELLED_STATE:
597 657 handler.Cancel();
598 658 break;
599 659 default:
600 660 // do nothing
601 661 return;
602 662 }
603 663 }
604 664
605 665 void OnStateChanged() {
606 666 AbstractHandler handler;
607 667 while (m_handlers.TryDequeue(out handler))
608 668 InvokeHandler(handler);
609 669 }
610 670
611 671 public bool IsExclusive {
612 672 get {
613 673 return m_childrenCount <= 1;
614 674 }
615 675 }
616 676
617 677 /// <summary>
618 678 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
619 679 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
620 680 /// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ обСщания, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ обСщания Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹, Ссли Π½ΠΈΠΊΡ‚ΠΎ большС Π½Π° Π½ΠΈΡ… Π½Π΅ подписан.
621 681 /// </summary>
622 682 /// <param name="promises">Бписок ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. Если список пустой, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ возвращаСтся ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΌ.</param>
623 683 /// <returns>ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.</returns>
624 684 /// <exception cref="ArgumentNullException"><paramref name="promises"/> Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ null</exception>
625 685 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
626 686 if (promises == null)
627 687 throw new ArgumentNullException();
628 688
629 689 // создаСм аккумулятор для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
630 690 var result = new T[promises.Count];
631 691 var promise = new Promise<T[]>();
632 692
633 693 // special case
634 694 if (promises.Count == 0) {
635 695 promise.Resolve(result);
636 696 return promise;
637 697 }
638 698
639 699 int pending = promises.Count;
640 700
641 701 for (int i = 0; i < promises.Count; i++) {
642 702 var dest = i;
643 703
644 704 if (promises[i] != null) {
645 705 promises[i].On(
646 706 x => {
647 707 result[dest] = x;
648 708 if (Interlocked.Decrement(ref pending) == 0)
649 709 promise.Resolve(result);
650 710 },
651 711 promise.Reject
652 712 );
653 713 } else {
654 714 if (Interlocked.Decrement(ref pending) == 0)
655 715 promise.Resolve(result);
656 716 }
657 717 }
658 718
659 719 promise.Cancelled(
660 720 () => {
661 721 foreach (var d in promises)
662 722 if (d != null && d.IsExclusive)
663 723 d.Cancel();
664 724 }
665 725 );
666 726
667 727 return promise;
668 728 }
669 729
670 730 /// <summary>
671 731 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
672 732 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
673 733 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
674 734 /// </summary>
675 735 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
676 736 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
677 737 /// <remarks>
678 738 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
679 739 /// </remarks>
680 740 public static IPromise CreateComposite(ICollection<IPromise> promises) {
681 741 if (promises == null)
682 742 throw new ArgumentNullException();
683 743 if (promises.Count == 0)
684 744 return Promise<object>.ResultToPromise(null);
685 745
686 746 int countdown = promises.Count;
687 747
688 748 var result = new Promise<object>();
689 749
690 750 foreach (var d in promises) {
691 751 if (d == null) {
692 752 if (Interlocked.Decrement(ref countdown) == 0)
693 753 result.Resolve(null);
694 754 } else {
695 755 d.Then(() => {
696 756 if (Interlocked.Decrement(ref countdown) == 0)
697 757 result.Resolve(null);
698 758 });
699 759 }
700 760 }
701 761
702 762 result.Cancelled(() => {
703 763 foreach (var d in promises)
704 764 if (d != null && d.IsExclusive)
705 765 d.Cancel();
706 766 });
707 767
708 768 return result;
709 769 }
710 770
711 771 public static Promise<T> ResultToPromise(T result) {
712 772 var p = new Promise<T>();
713 773 p.Resolve(result);
714 774 return p;
715 775 }
716 776
717 777 public static Promise<T> ExceptionToPromise(Exception error) {
718 778 if (error == null)
719 779 throw new ArgumentNullException();
720 780
721 781 var p = new Promise<T>();
722 782 p.Reject(error);
723 783 return p;
724 784 }
725 785
726 786 #region IPromiseBase explicit implementation
727 787
728 788 IPromise IPromise.Then(Action success, Action<Exception> error, Action cancel) {
729 789 return Then(
730 790 success != null ? new Func<T,T>(x => {
731 791 success();
732 792 return x;
733 793 }) : null,
734 794 error != null ? new Func<Exception,T>(e => {
735 795 error(e);
736 796 return default(T);
737 797 }) : null,
738 798 cancel
739 799 );
740 800 }
741 801
742 802 IPromise IPromise.Then(Action success, Action<Exception> error) {
743 803 return Then(
744 804 success != null ? new Func<T,T>(x => {
745 805 success();
746 806 return x;
747 807 }) : null,
748 808 error != null ? new Func<Exception,T>(e => {
749 809 error(e);
750 810 return default(T);
751 811 }) : null
752 812 );
753 813 }
754 814
755 815 IPromise IPromise.Then(Action success) {
756 816 Safe.ArgumentNotNull(success, "success");
757 817 return Then(x => {
758 818 success();
759 819 return x;
760 820 });
761 821 }
762 822
763 823 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
764 824 return ChainNoResult(chained, error, cancel);
765 825 }
766 826
767 827 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
768 828 Safe.ArgumentNotNull(chained, "chained");
769 829
770 830 var medium = new Promise<object>(this);
771 831
772 832 Func<T,T> resultHandler = delegate {
773 833 if (medium.IsCancelled)
774 834 return default(T);
775 835
776 836 var promise = chained();
777 837
778 838 promise.On(
779 839 medium.Resolve,
780 840 medium.Reject,
781 841 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
782 842 );
783 843
784 844 // notify chained operation that it's not needed anymore
785 845 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
786 846 // зависит IsExclusive
787 847 medium.Cancelled(() => {
788 848 if (promise.IsExclusive)
789 849 promise.Cancel();
790 850 });
791 851
792 852 return default(T);
793 853 };
794 854
795 855 Func<Exception,T> errorHandler;
796 856
797 857 if (error != null)
798 858 errorHandler = delegate(Exception e) {
799 859 try {
800 860 var promise = error(e);
801 861
802 862 promise.On(
803 863 medium.Resolve,
804 864 medium.Reject,
805 865 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
806 866 );
807 867
808 868 // notify chained operation that it's not needed anymore
809 869 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
810 870 // зависит IsExclusive
811 871 medium.Cancelled(() => {
812 872 if (promise.IsExclusive)
813 873 promise.Cancel();
814 874 });
815 875 } catch (Exception e2) {
816 876 medium.Reject(e2);
817 877 }
818 878 return default(T);
819 879 };
820 880 else
821 881 errorHandler = err => {
822 882 medium.Reject(err);
823 883 return default(T);
824 884 };
825 885
826 886
827 887 Action cancelHandler;
828 888 if (cancel != null)
829 889 cancelHandler = () => {
830 890 if (cancel != null)
831 891 cancel();
832 892 medium.Cancel();
833 893 };
834 894 else
835 895 cancelHandler = medium.Cancel;
836 896
837 AddHandler(
897 AddMappers(
838 898 resultHandler,
839 899 errorHandler,
840 900 cancelHandler,
841 901 null,
842 902 true
843 903 );
844 904
845 905 return medium;
846 906 }
847 907
848 908 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) {
849 909 return ChainNoResult(chained, error, null);
850 910 }
851 911
852 912 IPromise IPromise.Chain(Func<IPromise> chained) {
853 913 return ChainNoResult(chained, null, null);
854 914 }
855 915
856 916
857 917 void IPromise.On(Action success, Action<Exception> error, Action cancel) {
858 918 On(success != null ? new Action<T>(x => success()) : null, error, cancel);
859 919 }
860 920
861 921 void IPromise.On(Action success, Action<Exception> error) {
862 922 On(x => success(), error, null);
863 923 }
864 924
865 925 void IPromise.On(Action success) {
866 926 On(x => success(), null, null);
867 927 }
868 928
869 929 IPromise IPromise.Error(Action<Exception> error) {
870 930 return Error(error);
871 931 }
872 932
873 933 IPromise IPromise.Anyway(Action handler) {
874 934 return Anyway(handler);
875 935 }
876 936
877 937 IPromise IPromise.Cancelled(Action handler) {
878 938 return Cancelled(handler);
879 939 }
880 940
881 941 void IPromise.Join() {
882 942 Join();
883 943 }
884 944
885 945 void IPromise.Join(int timeout) {
886 946 Join(timeout);
887 947 }
888 948
889 949 #endregion
890 950
891 951
892 952
893 953 }
894 954 }
General Comments 0
You need to be logged in to leave comments. Login now