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