##// END OF EJS Templates
Fixed chaining of promises with 'Then' method
cin -
r135:656815cb7147 v2
parent child
Show More
@@ -1,622 +1,628
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Diagnostics;
3
3
4 namespace Implab {
4 namespace Implab {
5
5
6 /// <summary>
6 /// <summary>
7 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
7 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
8 /// </summary>
8 /// </summary>
9 /// <typeparam name="T">Π’ΠΈΠΏ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°</typeparam>
9 /// <typeparam name="T">Π’ΠΈΠΏ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°</typeparam>
10 /// <remarks>
10 /// <remarks>
11 /// <para>БСрвис ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π΄Π°Π΅Ρ‚ ΠΎΠ±Π΅Ρ‰Π°ΠΈΠ½ΠΈΠ΅ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ,
11 /// <para>БСрвис ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π΄Π°Π΅Ρ‚ ΠΎΠ±Π΅Ρ‰Π°ΠΈΠ½ΠΈΠ΅ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ,
12 /// ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ² Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ряд ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎ для получСния
12 /// ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ² Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ряд ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎ для получСния
13 /// событий выполнСния обСщания, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ прСдоставлСнии Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².</para>
13 /// событий выполнСния обСщания, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ прСдоставлСнии Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².</para>
14 /// <para>
14 /// <para>
15 /// ΠžΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ с ошибкой. Для подписки Π½Π°
15 /// ΠžΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ с ошибкой. Для подписки Π½Π°
16 /// Π΄Π°Π½Π½Ρ‹Π΅ события ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Then</c>.
16 /// Π΄Π°Π½Π½Ρ‹Π΅ события ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Then</c>.
17 /// </para>
17 /// </para>
18 /// <para>
18 /// <para>
19 /// БСрвис, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ошибкой),
19 /// БСрвис, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ошибкой),
20 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Resolve</c> Π»ΠΈΠ±ΠΎ <c>Reject</c> для оповСщСния ΠΊΠ»ΠΈΠ΅Ρ‚Π½Π° ΠΎ
20 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Resolve</c> Π»ΠΈΠ±ΠΎ <c>Reject</c> для оповСщСния ΠΊΠ»ΠΈΠ΅Ρ‚Π½Π° ΠΎ
21 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ обСщания.
21 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ обСщания.
22 /// </para>
22 /// </para>
23 /// <para>
23 /// <para>
24 /// Если сСрвСр успСл Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° Π½Π΅Π³ΠΎ подписался,
24 /// Если сСрвСр успСл Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° Π½Π΅Π³ΠΎ подписался,
25 /// Ρ‚ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ подписки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠ΅ события Π² синхронном
25 /// Ρ‚ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ подписки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠ΅ события Π² синхронном
26 /// Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ Π² любом случаС. Π˜Π½Π°Ρ‡Π΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²
26 /// Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ Π² любом случаС. Π˜Π½Π°Ρ‡Π΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²
27 /// список Π² порядкС подписания ΠΈ Π² этом ΠΆΠ΅ порядкС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ
27 /// список Π² порядкС подписания ΠΈ Π² этом ΠΆΠ΅ порядкС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ
28 /// обСщания.
28 /// обСщания.
29 /// </para>
29 /// </para>
30 /// <para>
30 /// <para>
31 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обСщания ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
31 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обСщания ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
32 /// связанныС асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ обСщания. Для этого слСдуСт
32 /// связанныС асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ обСщания. Для этого слСдуСт
33 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ <c>Then</c>.
33 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ <c>Then</c>.
34 /// </para>
34 /// </para>
35 /// <para>
35 /// <para>
36 /// Π’Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ <c>Resolve</c> ΠΈ <c>Reject</c> Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
36 /// Π’Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ <c>Resolve</c> ΠΈ <c>Reject</c> Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
37 /// Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΎΡ€ обСщания ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ противорСчия.
37 /// Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΎΡ€ обСщания ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ противорСчия.
38 /// </para>
38 /// </para>
39 /// </remarks>
39 /// </remarks>
40 public class Promise<T> : AbstractPromise<IDeferred<T>>, IPromise<T>, IDeferred<T> {
40 public class Promise<T> : AbstractPromise<IDeferred<T>>, IPromise<T>, IDeferred<T> {
41
41
42 class StubDeferred : IDeferred<T> {
42 class StubDeferred : IDeferred<T> {
43 public static readonly StubDeferred instance = new StubDeferred();
43 public static readonly StubDeferred instance = new StubDeferred();
44
44
45 StubDeferred() {
45 StubDeferred() {
46 }
46 }
47
47
48 #region IDeferred implementation
48 #region IDeferred implementation
49
49
50 public void Resolve(T value) {
50 public void Resolve(T value) {
51 }
51 }
52
52
53 public void Reject(Exception error) {
53 public void Reject(Exception error) {
54 }
54 }
55
55
56 #endregion
56 #endregion
57
57
58 #region ICancellable implementation
58 #region ICancellable implementation
59
59
60 public void Cancel() {
60 public void Cancel() {
61 }
61 }
62
62
63 #endregion
63 #endregion
64
64
65
65
66 }
66 }
67
67
68 class RemapDescriptor<T2> : IDeferred<T> {
68 class RemapDescriptor<T2> : IDeferred<T> {
69 readonly Func<T,T2> m_remap;
69 readonly Func<T,T2> m_remap;
70 readonly Func<Exception,T2> m_failed;
70 readonly Func<Exception,T2> m_failed;
71 readonly Func<T2> m_cancel;
71 readonly Func<T2> m_cancel;
72 readonly IDeferred<T2> m_deferred;
72 readonly IDeferred<T2> m_deferred;
73
73
74 public RemapDescriptor(Func<T,T2> remap, Func<Exception,T2> failed, Func<T2> cancel, IDeferred<T2> deferred ) {
74 public RemapDescriptor(Func<T,T2> remap, Func<Exception,T2> failed, Func<T2> cancel, IDeferred<T2> deferred ) {
75 Debug.Assert(deferred != null);
75 Debug.Assert(deferred != null);
76 m_remap = remap;
76 m_remap = remap;
77 m_failed = failed;
77 m_failed = failed;
78 m_cancel = cancel;
78 m_cancel = cancel;
79 m_deferred = deferred;
79 m_deferred = deferred;
80 }
80 }
81
81
82
82
83
83
84 #region IDeferred implementation
84 #region IDeferred implementation
85
85
86 public void Resolve(T value) {
86 public void Resolve(T value) {
87 if (m_remap != null) {
87 if (m_remap != null) {
88 try {
88 try {
89 m_deferred.Resolve(m_remap(value));
89 m_deferred.Resolve(m_remap(value));
90 } catch (Exception ex) {
90 } catch (Exception ex) {
91 Reject(ex);
91 Reject(ex);
92 }
92 }
93 }
93 }
94 }
94 }
95
95
96 public void Reject(Exception error) {
96 public void Reject(Exception error) {
97 if (m_failed != null) {
97 if (m_failed != null) {
98 try {
98 try {
99 m_deferred.Resolve(m_failed(error));
99 m_deferred.Resolve(m_failed(error));
100 } catch (Exception ex) {
100 } catch (Exception ex) {
101 m_deferred.Reject(ex);
101 m_deferred.Reject(ex);
102 }
102 }
103 } else {
103 } else {
104 m_deferred.Reject(error);
104 m_deferred.Reject(error);
105 }
105 }
106 }
106 }
107
107
108
108
109 #endregion
109 #endregion
110
110
111 #region ICancellable implementation
111 #region ICancellable implementation
112
112
113 public void Cancel() {
113 public void Cancel() {
114 if (m_cancel != null) {
114 if (m_cancel != null) {
115 try {
115 try {
116 m_deferred.Resolve(m_cancel());
116 m_deferred.Resolve(m_cancel());
117 } catch (Exception ex) {
117 } catch (Exception ex) {
118 Reject(ex);
118 Reject(ex);
119 }
119 }
120 } else {
120 } else {
121 m_deferred.Cancel();
121 m_deferred.Cancel();
122 }
122 }
123 }
123 }
124
124
125 #endregion
125 #endregion
126 }
126 }
127
127
128 class ListenerDescriptor : IDeferred<T> {
128 class ListenerDescriptor : IDeferred<T> {
129 readonly Action m_handler;
129 readonly Action m_handler;
130 readonly PromiseEventType m_events;
130 readonly PromiseEventType m_events;
131
131
132 public ListenerDescriptor(Action handler, PromiseEventType events) {
132 public ListenerDescriptor(Action handler, PromiseEventType events) {
133 Debug.Assert(handler != null);
133 Debug.Assert(handler != null);
134
134
135 m_handler = handler;
135 m_handler = handler;
136 m_events = events;
136 m_events = events;
137 }
137 }
138
138
139 #region IDeferred implementation
139 #region IDeferred implementation
140
140
141 public void Resolve(T value) {
141 public void Resolve(T value) {
142 if (m_events.HasFlag(PromiseEventType.Success)) {
142 if (m_events.HasFlag(PromiseEventType.Success)) {
143 try {
143 try {
144 m_handler();
144 m_handler();
145 // Analysis disable once EmptyGeneralCatchClause
145 // Analysis disable once EmptyGeneralCatchClause
146 } catch {
146 } catch {
147 }
147 }
148 }
148 }
149 }
149 }
150
150
151 public void Reject(Exception error) {
151 public void Reject(Exception error) {
152 if (m_events.HasFlag(PromiseEventType.Error)){
152 if (m_events.HasFlag(PromiseEventType.Error)){
153 try {
153 try {
154 m_handler();
154 m_handler();
155 // Analysis disable once EmptyGeneralCatchClause
155 // Analysis disable once EmptyGeneralCatchClause
156 } catch {
156 } catch {
157 }
157 }
158 }
158 }
159 }
159 }
160
160
161 #endregion
161 #endregion
162
162
163 #region ICancellable implementation
163 #region ICancellable implementation
164
164
165 public void Cancel() {
165 public void Cancel() {
166 if (m_events.HasFlag(PromiseEventType.Cancelled)){
166 if (m_events.HasFlag(PromiseEventType.Cancelled)){
167 try {
167 try {
168 m_handler();
168 m_handler();
169 // Analysis disable once EmptyGeneralCatchClause
169 // Analysis disable once EmptyGeneralCatchClause
170 } catch {
170 } catch {
171 }
171 }
172 }
172 }
173 }
173 }
174
174
175 #endregion
175 #endregion
176 }
176 }
177
177
178 class ValueEventDescriptor : IDeferred<T> {
178 class ValueEventDescriptor : IDeferred<T> {
179 readonly Action<T> m_success;
179 readonly Action<T> m_success;
180 readonly Action<Exception> m_failed;
180 readonly Action<Exception> m_failed;
181 readonly Action m_cancelled;
181 readonly Action m_cancelled;
182 readonly IDeferred<T> m_deferred;
182 readonly IDeferred<T> m_deferred;
183
183
184 public ValueEventDescriptor(Action<T> success, Action<Exception> failed, Action cancelled, IDeferred<T> deferred) {
184 public ValueEventDescriptor(Action<T> success, Action<Exception> failed, Action cancelled, IDeferred<T> deferred) {
185 Debug.Assert(deferred != null);
185 Debug.Assert(deferred != null);
186
186
187 m_success = success;
187 m_success = success;
188 m_failed = failed;
188 m_failed = failed;
189 m_cancelled = cancelled;
189 m_cancelled = cancelled;
190 m_deferred = deferred;
190 m_deferred = deferred;
191 }
191 }
192
192
193 #region IDeferred implementation
193 #region IDeferred implementation
194
194
195 public void Resolve(T value) {
195 public void Resolve(T value) {
196 if (m_success != null) {
196 if (m_success != null) {
197 try {
197 try {
198 m_success(value);
198 m_success(value);
199 m_deferred.Resolve(value);
199 m_deferred.Resolve(value);
200 } catch (Exception ex) {
200 } catch (Exception ex) {
201 Reject(ex);
201 Reject(ex);
202 }
202 }
203 }
203 }
204 }
204 }
205
205
206 public void Reject(Exception error) {
206 public void Reject(Exception error) {
207 if (m_failed != null) {
207 if (m_failed != null) {
208 try {
208 try {
209 m_failed(error);
209 m_failed(error);
210 m_deferred.Resolve(default(T));
210 m_deferred.Resolve(default(T));
211 } catch(Exception ex) {
211 } catch(Exception ex) {
212 m_deferred.Reject(ex);
212 m_deferred.Reject(ex);
213 }
213 }
214 } else {
214 } else {
215 m_deferred.Reject(error);
215 m_deferred.Reject(error);
216 }
216 }
217 }
217 }
218
218
219 #endregion
219 #endregion
220
220
221 #region ICancellable implementation
221 #region ICancellable implementation
222
222
223 public void Cancel() {
223 public void Cancel() {
224 if (m_cancelled != null) {
224 if (m_cancelled != null) {
225 try {
225 try {
226 m_cancelled();
226 m_cancelled();
227 m_deferred.Resolve(default(T));
227 m_deferred.Resolve(default(T));
228 } catch(Exception ex) {
228 } catch(Exception ex) {
229 Reject(ex);
229 Reject(ex);
230 }
230 }
231 } else {
231 } else {
232 m_deferred.Cancel();
232 m_deferred.Cancel();
233 }
233 }
234 }
234 }
235
235
236 #endregion
236 #endregion
237 }
237 }
238
238
239 public class EventDescriptor : IDeferred<T> {
239 public class EventDescriptor : IDeferred<T> {
240 readonly Action m_success;
240 readonly Action m_success;
241 readonly Action<Exception> m_failed;
241 readonly Action<Exception> m_failed;
242 readonly Action m_cancelled;
242 readonly Action m_cancelled;
243 readonly IDeferred<T> m_deferred;
243 readonly IDeferred<T> m_deferred;
244
244
245 public EventDescriptor(Action success, Action<Exception> failed, Action cancelled, IDeferred<T> deferred) {
245 public EventDescriptor(Action success, Action<Exception> failed, Action cancelled, IDeferred<T> deferred) {
246 Debug.Assert(deferred != null);
246 Debug.Assert(deferred != null);
247
247
248 m_success = success;
248 m_success = success;
249 m_failed = failed;
249 m_failed = failed;
250 m_cancelled = cancelled;
250 m_cancelled = cancelled;
251 m_deferred = deferred;
251 m_deferred = deferred;
252 }
252 }
253
253
254 #region IDeferred implementation
254 #region IDeferred implementation
255
255
256 public void Resolve(T value) {
256 public void Resolve(T value) {
257 if (m_success != null) {
257 if (m_success != null) {
258 try {
258 try {
259 m_success();
259 m_success();
260 m_deferred.Resolve(value);
260 m_deferred.Resolve(value);
261 } catch (Exception ex) {
261 } catch (Exception ex) {
262 Reject(ex);
262 Reject(ex);
263 }
263 }
264 }
264 }
265 }
265 }
266
266
267 public void Reject(Exception error) {
267 public void Reject(Exception error) {
268 if (m_failed != null) {
268 if (m_failed != null) {
269 try {
269 try {
270 m_failed(error);
270 m_failed(error);
271 m_deferred.Resolve(default(T));
271 m_deferred.Resolve(default(T));
272 }catch (Exception ex)
272 }catch (Exception ex)
273 {
273 {
274 m_deferred.Reject(ex);
274 m_deferred.Reject(ex);
275 }
275 }
276 } else {
276 } else {
277 m_deferred.Reject(error);
277 m_deferred.Reject(error);
278 }
278 }
279
279
280 }
280 }
281
281
282 #endregion
282 #endregion
283
283
284 #region ICancellable implementation
284 #region ICancellable implementation
285
285
286 public void Cancel() {
286 public void Cancel() {
287 if (m_cancelled != null) {
287 if (m_cancelled != null) {
288 try {
288 try {
289 m_cancelled();
289 m_cancelled();
290 m_deferred.Resolve(default(T));
290 m_deferred.Resolve(default(T));
291 } catch (Exception ex) {
291 } catch (Exception ex) {
292 Reject(ex);
292 Reject(ex);
293 }
293 }
294 } else {
294 } else {
295 m_deferred.Cancel();
295 m_deferred.Cancel();
296 }
296 }
297 }
297 }
298
298
299 #endregion
299 #endregion
300 }
300 }
301
301
302 T m_result;
302 T m_result;
303
303
304 public virtual void Resolve(T value) {
304 public virtual void Resolve(T value) {
305 if (BeginSetResult()) {
305 if (BeginSetResult()) {
306 m_result = value;
306 m_result = value;
307 EndSetResult();
307 EndSetResult();
308 }
308 }
309 }
309 }
310
310
311 public void Reject(Exception error) {
311 public void Reject(Exception error) {
312 SetError(error);
312 SetError(error);
313 }
313 }
314
314
315 public Type PromiseType {
315 public Type PromiseType {
316 get {
316 get {
317 return typeof(T);
317 return typeof(T);
318 }
318 }
319 }
319 }
320
320
321 public new T Join() {
321 public new T Join() {
322 WaitResult(-1);
322 WaitResult(-1);
323 return m_result;
323 return m_result;
324 }
324 }
325 public new T Join(int timeout) {
325 public new T Join(int timeout) {
326 WaitResult(timeout);
326 WaitResult(timeout);
327 return m_result;
327 return m_result;
328 }
328 }
329
329
330 public IPromise<T> On(Action<T> success, Action<Exception> error, Action cancel) {
330 public IPromise<T> On(Action<T> success, Action<Exception> error, Action cancel) {
331 AddHandler(new ValueEventDescriptor(success, error, cancel, StubDeferred.instance));
331 AddHandler(new ValueEventDescriptor(success, error, cancel, StubDeferred.instance));
332 return this;
332 return this;
333 }
333 }
334
334
335 public IPromise<T> On(Action<T> success, Action<Exception> error) {
335 public IPromise<T> On(Action<T> success, Action<Exception> error) {
336 AddHandler(new ValueEventDescriptor(success, error, null, StubDeferred.instance));
336 AddHandler(new ValueEventDescriptor(success, error, null, StubDeferred.instance));
337 return this;
337 return this;
338 }
338 }
339
339
340 public IPromise<T> On(Action<T> success) {
340 public IPromise<T> On(Action<T> success) {
341 AddHandler(new ValueEventDescriptor(success, null, null, StubDeferred.instance));
341 AddHandler(new ValueEventDescriptor(success, null, null, StubDeferred.instance));
342 return this;
342 return this;
343 }
343 }
344
344
345 public IPromise<T> On(Action handler, PromiseEventType events) {
345 public IPromise<T> On(Action handler, PromiseEventType events) {
346 Listen(events, handler);
346 Listen(events, handler);
347 return this;
347 return this;
348 }
348 }
349
349
350 public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error, Func<T2> cancel) {
350 public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error, Func<T2> cancel) {
351 var promise = new Promise<T2>();
351 var promise = new Promise<T2>();
352 if (mapper != null)
353 promise.On(Cancel, PromiseEventType.Cancelled);
352 AddHandler(new RemapDescriptor<T2>(mapper, error, cancel, promise));
354 AddHandler(new RemapDescriptor<T2>(mapper, error, cancel, promise));
353 return promise;
355 return promise;
354 }
356 }
355
357
356 public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error) {
358 public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error) {
357 var promise = new Promise<T2>();
359 var promise = new Promise<T2>();
360 if (mapper != null)
361 promise.On(Cancel, PromiseEventType.Cancelled);
358 AddHandler(new RemapDescriptor<T2>(mapper, error, null, promise));
362 AddHandler(new RemapDescriptor<T2>(mapper, error, null, promise));
359 return promise;
363 return promise;
360 }
364 }
361
365
362 public IPromise<T2> Then<T2>(Func<T, T2> mapper) {
366 public IPromise<T2> Then<T2>(Func<T, T2> mapper) {
363 var promise = new Promise<T2>();
367 var promise = new Promise<T2>();
368 if (mapper != null)
369 promise.On(Cancel, PromiseEventType.Cancelled);
364 AddHandler(new RemapDescriptor<T2>(mapper, null, null, promise));
370 AddHandler(new RemapDescriptor<T2>(mapper, null, null, promise));
365 return promise;
371 return promise;
366 }
372 }
367
373
368 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error, Func<IPromise<T2>> cancel) {
374 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error, Func<IPromise<T2>> cancel) {
369 // this promise will be resolved when an asyc operation is started
375 // this promise will be resolved when an asyc operation is started
370 var promise = new Promise<IPromise<T2>>();
376 var promise = new Promise<IPromise<T2>>();
371
377
372 AddHandler(new RemapDescriptor<IPromise<T2>>(
378 AddHandler(new RemapDescriptor<IPromise<T2>>(
373 chained,
379 chained,
374 error,
380 error,
375 cancel,
381 cancel,
376 promise
382 promise
377 ));
383 ));
378
384
379 var medium = new Promise<T2>();
385 var medium = new Promise<T2>();
380
386
381 if (chained != null)
387 if (chained != null)
382 medium.On(Cancel, PromiseEventType.Cancelled);
388 medium.On(Cancel, PromiseEventType.Cancelled);
383
389
384 // we need to connect started async operation with the medium
390 // we need to connect started async operation with the medium
385 // if the async operation hasn't been started by the some reason
391 // if the async operation hasn't been started by the some reason
386 // report is to the medium
392 // report is to the medium
387 promise.On(
393 promise.On(
388 result => ConnectPromise<T2>(result, medium),
394 result => ConnectPromise<T2>(result, medium),
389 medium.Reject,
395 medium.Reject,
390 medium.Cancel
396 medium.Cancel
391 );
397 );
392
398
393 return medium;
399 return medium;
394 }
400 }
395
401
396 static void ConnectPromise<T2>(IPromise<T2> result, Promise<T2> medium) {
402 static void ConnectPromise<T2>(IPromise<T2> result, Promise<T2> medium) {
397 if (result != null) {
403 if (result != null) {
398 result.On(
404 result.On(
399 medium.Resolve,
405 medium.Resolve,
400 medium.Reject,
406 medium.Reject,
401 () => medium.Reject(new OperationCanceledException())
407 () => medium.Reject(new OperationCanceledException())
402 );
408 );
403 medium.On(result.Cancel, PromiseEventType.Cancelled);
409 medium.On(result.Cancel, PromiseEventType.Cancelled);
404 } else {
410 } else {
405 medium.Reject(
411 medium.Reject(
406 new NullReferenceException(
412 new NullReferenceException(
407 "The chained asynchronous operation returned" +
413 "The chained asynchronous operation returned" +
408 " 'null' where the promise instance is expected"
414 " 'null' where the promise instance is expected"
409 )
415 )
410 );
416 );
411 }
417 }
412 }
418 }
413
419
414 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error) {
420 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error) {
415 return Chain(chained, error, null);
421 return Chain(chained, error, null);
416 }
422 }
417
423
418 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained) {
424 public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained) {
419 return Chain(chained, null, null);
425 return Chain(chained, null, null);
420 }
426 }
421
427
422 public IPromise<T2> Error<T2>(Func<Exception, T2> error) {
428 public IPromise<T2> Error<T2>(Func<Exception, T2> error) {
423 var promise = new Promise<T2>();
429 var promise = new Promise<T2>();
424 if (error != null)
430 if (error != null)
425 On(
431 On(
426 (Action<T>)null,
432 (Action<T>)null,
427 ex => {
433 ex => {
428 try {
434 try {
429 promise.Resolve(error(ex));
435 promise.Resolve(error(ex));
430 } catch (Exception ex2) {
436 } catch (Exception ex2) {
431 promise.Reject(ex2);
437 promise.Reject(ex2);
432 }
438 }
433 }
439 }
434 );
440 );
435 else
441 else
436 Listen(PromiseEventType.Error, () => promise.Resolve(default(T2)));
442 Listen(PromiseEventType.Error, () => promise.Resolve(default(T2)));
437 return promise;
443 return promise;
438 }
444 }
439
445
440 public IPromise<T2> Cancelled<T2>(Func<T2> handler) {
446 public IPromise<T2> Cancelled<T2>(Func<T2> handler) {
441 var promise = new Promise<T2>();
447 var promise = new Promise<T2>();
442 if (handler != null)
448 if (handler != null)
443 On(
449 On(
444 (Action<T>)null,
450 (Action<T>)null,
445 null,
451 null,
446 () => {
452 () => {
447 try {
453 try {
448 promise.Resolve(handler());
454 promise.Resolve(handler());
449 } catch (Exception ex) {
455 } catch (Exception ex) {
450 promise.Reject(ex);
456 promise.Reject(ex);
451 }
457 }
452 });
458 });
453 else
459 else
454 Listen(PromiseEventType.Cancelled, () => promise.Resolve(default(T2)));
460 Listen(PromiseEventType.Cancelled, () => promise.Resolve(default(T2)));
455 return promise;
461 return promise;
456 }
462 }
457
463
458 public IPromise Then(Action success, Action<Exception> error, Action cancel) {
464 public IPromise Then(Action success, Action<Exception> error, Action cancel) {
459 var promise = new Promise<T>();
465 var promise = new Promise<T>();
460 if (success != null)
466 if (success != null)
461 promise.On(Cancel, PromiseEventType.Cancelled);
467 promise.On(Cancel, PromiseEventType.Cancelled);
462
468
463 AddHandler(new EventDescriptor(success, error, cancel, promise));
469 AddHandler(new EventDescriptor(success, error, cancel, promise));
464
470
465 return promise;
471 return promise;
466 }
472 }
467
473
468 public IPromise Then(Action success, Action<Exception> error) {
474 public IPromise Then(Action success, Action<Exception> error) {
469 return Then(success, error, null);
475 return Then(success, error, null);
470 }
476 }
471
477
472 public IPromise Then(Action success) {
478 public IPromise Then(Action success) {
473 return Then(success, null, null);
479 return Then(success, null, null);
474 }
480 }
475
481
476 public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<IPromise> cancel) {
482 public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<IPromise> cancel) {
477 var promise = new Promise<IPromise>();
483 var promise = new Promise<IPromise>();
478
484
479 AddHandler(
485 AddHandler(
480 new RemapDescriptor<IPromise>(
486 new RemapDescriptor<IPromise>(
481 x => chained(),
487 x => chained(),
482 error,
488 error,
483 cancel,
489 cancel,
484 promise
490 promise
485 )
491 )
486 );
492 );
487
493
488 var medium = new Promise();
494 var medium = new Promise();
489 if (chained != null)
495 if (chained != null)
490 medium.On(Cancel, PromiseEventType.Cancelled);
496 medium.On(Cancel, PromiseEventType.Cancelled);
491
497
492 promise.On(
498 promise.On(
493 result => ConnectPromise(result, medium),
499 result => ConnectPromise(result, medium),
494 medium.Reject,
500 medium.Reject,
495 medium.Cancel
501 medium.Cancel
496 );
502 );
497
503
498 return medium;
504 return medium;
499 }
505 }
500
506
501 static void ConnectPromise(IPromise result, Promise medium) {
507 static void ConnectPromise(IPromise result, Promise medium) {
502 if (result != null) {
508 if (result != null) {
503 result.On(
509 result.On(
504 medium.Resolve,
510 medium.Resolve,
505 medium.Reject,
511 medium.Reject,
506 () => medium.Reject(new OperationCanceledException())
512 () => medium.Reject(new OperationCanceledException())
507 );
513 );
508 medium.On(result.Cancel, PromiseEventType.Cancelled);
514 medium.On(result.Cancel, PromiseEventType.Cancelled);
509 } else {
515 } else {
510 medium.Reject(
516 medium.Reject(
511 new NullReferenceException(
517 new NullReferenceException(
512 "The chained asynchronous operation returned" +
518 "The chained asynchronous operation returned" +
513 " 'null' where the promise instance is expected"
519 " 'null' where the promise instance is expected"
514 )
520 )
515 );
521 );
516 }
522 }
517 }
523 }
518
524
519 public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error) {
525 public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error) {
520 return Chain(chained, error, null);
526 return Chain(chained, error, null);
521 }
527 }
522
528
523 public IPromise Chain(Func<IPromise> chained) {
529 public IPromise Chain(Func<IPromise> chained) {
524 return Chain(chained, null, null);
530 return Chain(chained, null, null);
525 }
531 }
526
532
527 public IPromise On(Action success, Action<Exception> error, Action cancel) {
533 public IPromise On(Action success, Action<Exception> error, Action cancel) {
528 AddHandler(new EventDescriptor(success,error,cancel, StubDeferred.instance));
534 AddHandler(new EventDescriptor(success,error,cancel, StubDeferred.instance));
529 return this;
535 return this;
530 }
536 }
531
537
532 public IPromise On(Action success, Action<Exception> error) {
538 public IPromise On(Action success, Action<Exception> error) {
533 AddHandler(new EventDescriptor(success, error, null, StubDeferred.instance));
539 AddHandler(new EventDescriptor(success, error, null, StubDeferred.instance));
534 return this;
540 return this;
535 }
541 }
536
542
537 public IPromise On(Action success) {
543 public IPromise On(Action success) {
538 Listen(PromiseEventType.Success, success);
544 Listen(PromiseEventType.Success, success);
539 return this;
545 return this;
540 }
546 }
541
547
542 IPromise IPromise.On(Action handler, PromiseEventType events) {
548 IPromise IPromise.On(Action handler, PromiseEventType events) {
543 Listen(events,handler);
549 Listen(events,handler);
544 return this;
550 return this;
545 }
551 }
546
552
547 public IPromise Error(Action<Exception> error) {
553 public IPromise Error(Action<Exception> error) {
548 var promise = new Promise();
554 var promise = new Promise();
549 if (error != null)
555 if (error != null)
550 On(
556 On(
551 (Action<T>)null,
557 (Action<T>)null,
552 ex => {
558 ex => {
553 try {
559 try {
554 error(ex);
560 error(ex);
555 promise.Resolve();
561 promise.Resolve();
556 } catch (Exception ex2) {
562 } catch (Exception ex2) {
557 promise.Reject(ex2);
563 promise.Reject(ex2);
558 }
564 }
559 });
565 });
560 else
566 else
561 Listen(PromiseEventType.Error, promise.Resolve);
567 Listen(PromiseEventType.Error, promise.Resolve);
562 return promise;
568 return promise;
563 }
569 }
564
570
565 public IPromise Cancelled(Action handler) {
571 public IPromise Cancelled(Action handler) {
566 var promise = new Promise();
572 var promise = new Promise();
567 if (handler != null)
573 if (handler != null)
568 On(
574 On(
569 (Action<T>)null,
575 (Action<T>)null,
570 null,
576 null,
571 () => {
577 () => {
572 try {
578 try {
573 handler();
579 handler();
574 promise.Resolve();
580 promise.Resolve();
575 } catch (Exception ex) {
581 } catch (Exception ex) {
576 promise.Reject(ex);
582 promise.Reject(ex);
577 }
583 }
578 });
584 });
579 else
585 else
580 Listen(PromiseEventType.Cancelled, promise.Resolve);
586 Listen(PromiseEventType.Cancelled, promise.Resolve);
581 return promise;
587 return promise;
582 }
588 }
583
589
584 public IPromise<T2> Cast<T2>() {
590 public IPromise<T2> Cast<T2>() {
585 return (IPromise<T2>)this;
591 return (IPromise<T2>)this;
586 }
592 }
587
593
588 #region implemented abstract members of AbstractPromise
594 #region implemented abstract members of AbstractPromise
589
595
590 protected override void SignalSuccess(IDeferred<T> handler) {
596 protected override void SignalSuccess(IDeferred<T> handler) {
591 handler.Resolve(m_result);
597 handler.Resolve(m_result);
592 }
598 }
593
599
594 protected override void SignalError(IDeferred<T> handler, Exception error) {
600 protected override void SignalError(IDeferred<T> handler, Exception error) {
595 handler.Reject(error);
601 handler.Reject(error);
596 }
602 }
597
603
598 protected override void SignalCancelled(IDeferred<T> handler) {
604 protected override void SignalCancelled(IDeferred<T> handler) {
599 handler.Cancel();
605 handler.Cancel();
600 }
606 }
601
607
602 protected override void Listen(PromiseEventType events, Action handler) {
608 protected override void Listen(PromiseEventType events, Action handler) {
603 if (handler != null)
609 if (handler != null)
604 AddHandler(new ListenerDescriptor(handler, events));
610 AddHandler(new ListenerDescriptor(handler, events));
605 }
611 }
606
612
607 #endregion
613 #endregion
608
614
609 public static IPromise<T> ResultToPromise(T value) {
615 public static IPromise<T> ResultToPromise(T value) {
610 var p = new Promise<T>();
616 var p = new Promise<T>();
611 p.Resolve(value);
617 p.Resolve(value);
612 return p;
618 return p;
613 }
619 }
614
620
615 public static IPromise<T> ExceptionToPromise(Exception error) {
621 public static IPromise<T> ExceptionToPromise(Exception error) {
616 var p = new Promise<T>();
622 var p = new Promise<T>();
617 p.Reject(error);
623 p.Reject(error);
618 return p;
624 return p;
619 }
625 }
620
626
621 }
627 }
622 }
628 }
General Comments 0
You need to be logged in to leave comments. Login now