##// END OF EJS Templates
removed the reference to the parent from the promise object this allows...
cin -
r33:b255e4aeef17 default
parent child
Show More
@@ -328,6 +328,59 namespace Implab.Test {
328 Assert.IsTrue(flags[1]);
328 Assert.IsTrue(flags[1]);
329 Assert.IsTrue(flags[2]);
329 Assert.IsTrue(flags[2]);
330 }
330 }
331
332 [TestMethod]
333 public void ChainedCancel1Test() {
334 // ΠΏΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ сцСплСнной асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ всС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ
335 // Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ΡŒΡΡ ошибкой OperationCanceledException
336 var p = PromiseHelper
337 .Sleep(1, "Hi, HAL!")
338 .Chain(x => {
339 // запускаСм Π΄Π²Π΅ асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ
340 var result = PromiseHelper.Sleep(1000, "HEM ENABLED!!!");
341 // вторая опСрация отмСняСт ΠΏΠ΅Ρ€Π²ΡƒΡŽ Π΄ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ
342 PromiseHelper
343 .Sleep(100, "HAL, STOP!")
344 .Then(() => result.Cancel());
345 return result;
346 });
347 try {
348 p.Join();
349 } catch (TargetInvocationException err) {
350 Assert.IsTrue(err.InnerException is OperationCanceledException);
351 }
352 }
353
354 [TestMethod]
355 public void ChainedCancel2Test() {
356 // ΠΏΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΡ‚ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ
357 IPromiseBase p = null;
358 var pSurvive = new Promise<bool>();
359 var hemStarted = new ManualResetEvent(false);
360 p = PromiseHelper
361 .Sleep(1, "Hi, HAL!")
362 .Chain(x => {
363 hemStarted.Set();
364 // запускаСм Π΄Π²Π΅ асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ
365 var result = PromiseHelper
366 .Sleep(1000, "HEM ENABLED!!!")
367 .Then(s => pSurvive.Resolve(false));
368
369 result
370 .Cancelled(() => pSurvive.Resolve(true));
371
372 return result;
373 });
374
375 hemStarted.WaitOne();
376 p.Cancel();
377
378 try {
379 p.Join();
380 } catch (OperationCanceledException) {
381 Assert.IsTrue(pSurvive.Join());
382 }
383 }
331 }
384 }
332 }
385 }
333
386
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -8,14 +8,13 namespace Implab
8 public interface IPromise<T>: IPromiseBase
8 public interface IPromise<T>: IPromiseBase
9 {
9 {
10
10
11 T Join();
11 new T Join();
12
12 new T Join(int timeout);
13 T Join(int timeout);
14
13
15 IPromise<T> Then(ResultHandler<T> success, ErrorHandler error);
14 IPromise<T> Then(ResultHandler<T> success, ErrorHandler error);
16 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
15 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
17 IPromise<T> Then(ResultHandler<T> success);
16 IPromise<T> Then(ResultHandler<T> success);
18 IPromise<T> Error(ErrorHandler error);
17 new IPromise<T> Error(ErrorHandler error);
19 IPromise<T> Error(ErrorHandler<T> error);
18 IPromise<T> Error(ErrorHandler<T> error);
20
19
21 IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler error);
20 IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler error);
@@ -24,9 +23,9 namespace Implab
24 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler error);
23 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler error);
25 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained);
24 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained);
26
25
27 IPromise<T> Cancelled(Action handler);
26 new IPromise<T> Cancelled(Action handler);
28 IPromise<T> Finally(Action handler);
27 new IPromise<T> Finally(Action handler);
29 IPromise<T> Anyway(Action handler);
28 new IPromise<T> Anyway(Action handler);
30
29
31 }
30 }
32 }
31 }
@@ -23,8 +23,15 namespace Implab {
23
23
24 IPromiseBase Then(Action success,ErrorHandler error);
24 IPromiseBase Then(Action success,ErrorHandler error);
25 IPromiseBase Then(Action success);
25 IPromiseBase Then(Action success);
26 IPromiseBase Error(ErrorHandler error);
27 IPromiseBase Anyway(Action handler);
28 IPromiseBase Finally(Action handler);
29 IPromiseBase Cancelled(Action handler);
26
30
27 IPromise<T> Cast<T>();
31 IPromise<T> Cast<T>();
28
32
33 void Join();
34 void Join(int timeout);
35
29 }
36 }
30 }
37 }
@@ -11,7 +11,7 namespace Implab {
11 public delegate T ErrorHandler<out T>(Exception e);
11 public delegate T ErrorHandler<out T>(Exception e);
12 public delegate void ResultHandler<in T>(T result);
12 public delegate void ResultHandler<in T>(T result);
13 public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result);
13 public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result);
14 public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result);
14 public delegate IPromise<TNew> ChainedOperation<in TSrc, TNew>(TSrc result);
15
15
16 /// <summary>
16 /// <summary>
17 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
17 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
@@ -86,7 +86,6 namespace Implab {
86 const int RejectedState = 3;
86 const int RejectedState = 3;
87 const int CancelledState = 4;
87 const int CancelledState = 4;
88
88
89 readonly IPromiseBase m_parent;
90 readonly bool m_cancellable;
89 readonly bool m_cancellable;
91
90
92 int m_childrenCount = 0;
91 int m_childrenCount = 0;
@@ -102,12 +101,15 namespace Implab {
102
101
103 public Promise(IPromiseBase parent, bool cancellable) {
102 public Promise(IPromiseBase parent, bool cancellable) {
104 m_cancellable = cancellable;
103 m_cancellable = cancellable;
105 m_parent = parent;
104 if (parent != null)
106 }
105 AddHandler(
107
106 null,
108 void InternalCancel() {
107 null,
109 // don't try to cancel parent :)
108 () => {
110 Cancel(false);
109 if (parent.IsExclusive)
110 parent.Cancel();
111 }
112 );
111 }
113 }
112
114
113 bool BeginTransit() {
115 bool BeginTransit() {
@@ -159,6 +161,16 namespace Implab {
159 }
161 }
160
162
161 /// <summary>
163 /// <summary>
164 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
165 /// </summary>
166 /// <remarks>
167 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
168 /// </remarks>
169 public void Resolve() {
170 Resolve(default(T));
171 }
172
173 /// <summary>
162 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
174 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
163 /// </summary>
175 /// </summary>
164 /// <remarks>
176 /// <remarks>
@@ -185,7 +197,18 namespace Implab {
185 /// </summary>
197 /// </summary>
186 /// <returns><c>true</c> ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π±Ρ‹Π»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹.<c>false</c> ΠΎΡ‚ΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ.</returns>
198 /// <returns><c>true</c> ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π±Ρ‹Π»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹.<c>false</c> ΠΎΡ‚ΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ.</returns>
187 public bool Cancel() {
199 public bool Cancel() {
188 return Cancel(true);
200 if (BeginTransit()) {
201 CompleteTransit(CancelledState);
202 OnStateChanged();
203 return true;
204 } else {
205 return false;
206 }
207 }
208
209 // сдСлано для Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° void
210 protected void InternalCancel() {
211 Cancel();
189 }
212 }
190
213
191 /// <summary>
214 /// <summary>
@@ -229,13 +252,11 namespace Implab {
229 return medium;
252 return medium;
230 }
253 }
231
254
232 public IPromiseBase Then(Action success,ErrorHandler error)
255 public IPromiseBase Then(Action success, ErrorHandler error) {
233 {
234 return Then(x => success(), error);
256 return Then(x => success(), error);
235 }
257 }
236
258
237 public IPromiseBase Then(Action success)
259 public IPromiseBase Then(Action success) {
238 {
239 return Then(x => success());
260 return Then(x => success());
240 }
261 }
241
262
@@ -267,7 +288,7 namespace Implab {
267 errorHandler = x => {
288 errorHandler = x => {
268 try {
289 try {
269 medium.Resolve(error(x));
290 medium.Resolve(error(x));
270 } catch(Exception e) {
291 } catch (Exception e) {
271 medium.Reject(e);
292 medium.Reject(e);
272 }
293 }
273 };
294 };
@@ -338,7 +359,7 namespace Implab {
338 if (handler == null)
359 if (handler == null)
339 return this;
360 return this;
340
361
341 var medium = new Promise<T>();
362 var medium = new Promise<T>(this,true);
342
363
343 AddHandler(
364 AddHandler(
344 x => {
365 x => {
@@ -377,7 +398,7 namespace Implab {
377 throw new ArgumentNullException("mapper");
398 throw new ArgumentNullException("mapper");
378
399
379 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
400 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
380 var chained = new Promise<TNew>();
401 var chained = new Promise<TNew>(this,true);
381
402
382 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
403 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
383 ErrorHandler errorHandler = delegate(Exception e) {
404 ErrorHandler errorHandler = delegate(Exception e) {
@@ -427,12 +448,21 namespace Implab {
427
448
428 var promise = chained(result);
449 var promise = chained(result);
429
450
430 // notify chained operation that it's not needed
431 medium.Cancelled(() => promise.Cancel());
432 promise.Then(
451 promise.Then(
433 x => medium.Resolve(x),
452 x => medium.Resolve(x),
434 e => medium.Reject(e)
453 e => medium.Reject(e)
435 );
454 );
455
456 // notify chained operation that it's not needed anymore
457 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
458 // зависит IsExclusive
459 medium.Cancelled(() => {
460 if(promise.IsExclusive)
461 promise.Cancel();
462 });
463
464 // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
465 promise.Cancelled(() => medium.Reject(new OperationCanceledException()));
436 };
466 };
437
467
438 ErrorHandler errorHandler = delegate(Exception e) {
468 ErrorHandler errorHandler = delegate(Exception e) {
@@ -531,7 +561,8 namespace Implab {
531 }
561 }
532
562
533 void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) {
563 void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) {
534 Interlocked.Increment(ref m_childrenCount);
564 if (success != null || error != null)
565 Interlocked.Increment(ref m_childrenCount);
535
566
536 HandlerDescriptor handler = new HandlerDescriptor {
567 HandlerDescriptor handler = new HandlerDescriptor {
537 resultHandler = success,
568 resultHandler = success,
@@ -588,20 +619,6 namespace Implab {
588 }
619 }
589 }
620 }
590
621
591 protected bool Cancel(bool dependencies) {
592 if (BeginTransit()) {
593 CompleteTransit(CancelledState);
594 OnStateChanged();
595
596 if (dependencies && m_parent != null && m_parent.IsExclusive)
597 m_parent.Cancel();
598
599 return true;
600 } else {
601 return false;
602 }
603 }
604
605 /// <summary>
622 /// <summary>
606 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
623 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
607 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
624 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
@@ -629,20 +646,25 namespace Implab {
629 for (int i = 0; i < promises.Count; i++) {
646 for (int i = 0; i < promises.Count; i++) {
630 var dest = i;
647 var dest = i;
631
648
632 promises[i].Then(
649 if (promises[i] != null) {
633 x => {
650 promises[i].Then(
634 result[dest] = x;
651 x => {
635 if(Interlocked.Decrement(ref pending) == 0)
652 result[dest] = x;
636 promise.Resolve(result);
653 if (Interlocked.Decrement(ref pending) == 0)
637 },
654 promise.Resolve(result);
638 e => promise.Reject(e)
655 },
639 );
656 e => promise.Reject(e)
657 );
658 } else {
659 if (Interlocked.Decrement(ref pending) == 0)
660 promise.Resolve(result);
661 }
640 }
662 }
641
663
642 promise.Cancelled(
664 promise.Cancelled(
643 () => {
665 () => {
644 foreach(var d in promises)
666 foreach (var d in promises)
645 if(d.IsExclusive)
667 if (d != null && d.IsExclusive)
646 d.Cancel();
668 d.Cancel();
647 }
669 }
648 );
670 );
@@ -650,6 +672,47 namespace Implab {
650 return promise;
672 return promise;
651 }
673 }
652
674
675 /// <summary>
676 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
677 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
678 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
679 /// </summary>
680 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
681 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
682 /// <remarks>
683 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
684 /// </remarks>
685 public static IPromiseBase CreateComposite(ICollection<IPromiseBase> promises) {
686 if (promises == null)
687 throw new ArgumentNullException();
688 if (promises.Count == 0)
689 return Promise<object>.ResultToPromise(null);
690
691 int countdown = promises.Count;
692
693 var result = new Promise<object>();
694
695 foreach (var d in promises) {
696 if (d == null) {
697 if (Interlocked.Decrement(ref countdown) == 0)
698 result.Resolve(null);
699 } else {
700 d.Then(() => {
701 if (Interlocked.Decrement(ref countdown) == 0)
702 result.Resolve(null);
703 });
704 }
705 }
706
707 result.Cancelled(() => {
708 foreach (var d in promises)
709 if (d != null && d.IsExclusive)
710 d.Cancel();
711 });
712
713 return result;
714 }
715
653 public static Promise<T> ResultToPromise(T result) {
716 public static Promise<T> ResultToPromise(T result) {
654 var p = new Promise<T>();
717 var p = new Promise<T>();
655 p.Resolve(result);
718 p.Resolve(result);
@@ -665,5 +728,35 namespace Implab {
665 return p;
728 return p;
666 }
729 }
667
730
731 #region IPromiseBase explicit implementation
732
733 IPromiseBase IPromiseBase.Error(ErrorHandler error) {
734 return Error(error);
735 }
736
737 IPromiseBase IPromiseBase.Anyway(Action handler) {
738 return Anyway(handler);
739 }
740
741 IPromiseBase IPromiseBase.Finally(Action handler) {
742 return Finally(handler);
743 }
744
745 IPromiseBase IPromiseBase.Cancelled(Action handler) {
746 return Cancelled(handler);
747 }
748
749 void IPromiseBase.Join() {
750 Join();
751 }
752
753 void IPromiseBase.Join(int timeout) {
754 Join(timeout);
755 }
756
757 #endregion
758
759
760
668 }
761 }
669 }
762 }
General Comments 0
You need to be logged in to leave comments. Login now