##// END OF EJS Templates
renamed Promise.Last -> Promise.On...
cin -
r104:5f10d54b45df v2
parent child
Show More
@@ -0,0 +1,19
1 using System;
2
3 namespace Implab {
4 [Flags]
5 public enum PromiseEventType {
6 Success = 1,
7 Error = 2,
8 Cancelled = 4,
9 /// <summary>
10 /// Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π»ΠΈΠ±ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка,
11 /// </summary>
12 All = 7,
13 /// <summary>
14 /// Π—Π°Π²Ρ€Π΅ΡˆΠ΅Π½ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π»ΠΈΠ±ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка.
15 /// </summary>
16 Complete = 3
17 }
18 }
19
@@ -1,41 +1,41
1 using System;
1 using System;
2 using System.Windows.Forms;
2 using System.Windows.Forms;
3 using System.Threading;
3 using System.Threading;
4
4
5 namespace Implab.Fx
5 namespace Implab.Fx
6 {
6 {
7 public static class PromiseHelpers
7 public static class PromiseHelpers
8 {
8 {
9 /// <summary>
9 /// <summary>
10 /// ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ элСмСнта управлСния.
10 /// ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ элСмСнта управлСния.
11 /// </summary>
11 /// </summary>
12 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания</typeparam>
12 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания</typeparam>
13 /// <param name="that">Π˜ΡΡ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅</param>
13 /// <param name="that">Π˜ΡΡ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅</param>
14 /// <param name="ctl">Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ управлСния</param>
14 /// <param name="ctl">Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ управлСния</param>
15 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ элСмСнта управлСния.</returns>
15 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ элСмСнта управлСния.</returns>
16 /// <exception cref="ArgumentNullException">ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ <c>null</c>.</exception>
16 /// <exception cref="ArgumentNullException">ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ <c>null</c>.</exception>
17 /// <example>
17 /// <example>
18 /// client
18 /// client
19 /// .Get("description.txt") // returns a promise
19 /// .Get("description.txt") // returns a promise
20 /// .DispatchToControl(m_ctl) // handle the promise in the thread of the control
20 /// .DispatchToControl(m_ctl) // handle the promise in the thread of the control
21 /// .Then(
21 /// .Then(
22 /// description => m_ctl.Text = description // now it's safe
22 /// description => m_ctl.Text = description // now it's safe
23 /// )
23 /// )
24 /// </example>
24 /// </example>
25 public static IPromise<T> DispatchToControl<T>(this IPromise<T> that, Control ctl)
25 public static IPromise<T> DispatchToControl<T>(this IPromise<T> that, Control ctl)
26 {
26 {
27 Safe.ArgumentNotNull(that, "that");
27 Safe.ArgumentNotNull(that, "that");
28 Safe.ArgumentNotNull(ctl, "ctl");
28 Safe.ArgumentNotNull(ctl, "ctl");
29
29
30 var directed = new ControlBoundPromise<T>(ctl,that);
30 var directed = new ControlBoundPromise<T>(ctl,that);
31
31
32 that.Last(
32 that.On(
33 directed.Resolve,
33 directed.Resolve,
34 directed.Reject,
34 directed.Reject,
35 directed.Cancel
35 directed.Cancel
36 );
36 );
37
37
38 return directed;
38 return directed;
39 }
39 }
40 }
40 }
41 }
41 }
@@ -1,86 +1,87
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5
5
6 namespace Implab {
6 namespace Implab {
7 public interface IPromise: ICancellable {
7 public interface IPromise: ICancellable {
8 /// <summary>
8 /// <summary>
9 /// Check whereather the promise has no more than one dependent promise.
9 /// Check whereather the promise has no more than one dependent promise.
10 /// </summary>
10 /// </summary>
11 bool IsExclusive {
11 bool IsExclusive {
12 get;
12 get;
13 }
13 }
14
14
15 /// <summary>
15 /// <summary>
16 /// Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‡Π΅Ρ€Π΅Π· Π΄Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.
16 /// Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‡Π΅Ρ€Π΅Π· Π΄Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.
17 /// </summary>
17 /// </summary>
18 Type PromiseType { get; }
18 Type PromiseType { get; }
19
19
20 /// <summary>
20 /// <summary>
21 /// ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ являСтся Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ΠΌ, Π»ΠΈΠ±ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π»ΠΈΠ±ΠΎ с ошибкой, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ.
21 /// ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ являСтся Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ΠΌ, Π»ΠΈΠ±ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Π»ΠΈΠ±ΠΎ с ошибкой, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ.
22 /// </summary>
22 /// </summary>
23 bool IsResolved { get; }
23 bool IsResolved { get; }
24
24
25 /// <summary>
25 /// <summary>
26 /// ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ.
26 /// ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ.
27 /// </summary>
27 /// </summary>
28 bool IsCancelled { get; }
28 bool IsCancelled { get; }
29
29
30 IPromise Then(Action success, Action<Exception> error, Action cancel);
30 IPromise Then(Action success, Action<Exception> error, Action cancel);
31 IPromise Then(Action success, Action<Exception> error);
31 IPromise Then(Action success, Action<Exception> error);
32 IPromise Then(Action success);
32 IPromise Then(Action success);
33
33
34 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Action cancel);
34 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Action cancel);
35 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error);
35 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error);
36 IPromise Chain(Func<IPromise> chained);
36 IPromise Chain(Func<IPromise> chained);
37
37
38 /// <summary>
38 /// <summary>
39 /// ДобавляСт послСднй ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, Π½Π΅ создаСт ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
39 /// ДобавляСт послСднй ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, Π½Π΅ создаСт ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
40 /// </summary>
40 /// </summary>
41 /// <param name="success">Success.</param>
41 /// <param name="success">Success.</param>
42 /// <param name="error">Error.</param>
42 /// <param name="error">Error.</param>
43 /// <param name="cancel">Cancel.</param>
43 /// <param name="cancel">Cancel.</param>
44 void Last(Action success, Action<Exception> error, Action cancel);
44 void On(Action success, Action<Exception> error, Action cancel);
45 void Last(Action success, Action<Exception> error);
45 void On(Action success, Action<Exception> error);
46 void Last(Action success);
46 void On(Action success);
47 void On(Action success, PromiseEventType events);
47
48
48 IPromise Error(Action<Exception> error);
49 IPromise Error(Action<Exception> error);
49 /// <summary>
50 /// <summary>
50 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ.
51 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ.
51 /// </summary>
52 /// </summary>
52 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.</param>
53 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.</param>
53 /// <remarks>ПослС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ошибки, ΠΎΠ½Π° пСрСдаСтся дальшС.</remarks>
54 /// <remarks>ПослС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ошибки, ΠΎΠ½Π° пСрСдаСтся дальшС.</remarks>
54 /// <summary>
55 /// <summary>
55 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ обСщания.
56 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ обСщания.
56 /// </summary>
57 /// </summary>
57 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.</param>
58 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.</param>
58 /// <remarks>ПослС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ошибки, ΠΎΠ½Π° пСрСдаСтся дальшС.</remarks>
59 /// <remarks>ПослС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ошибки, ΠΎΠ½Π° пСрСдаСтся дальшС.</remarks>
59 IPromise Anyway(Action handler);
60 IPromise Anyway(Action handler);
60 /// <summary>
61 /// <summary>
61 /// ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для рСгистрации ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ обСщания.
62 /// ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для рСгистрации ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ обСщания.
62 /// </summary>
63 /// </summary>
63 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, связанноС с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ, выполнится послС ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.</returns>
64 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, связанноС с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ, выполнится послС ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.</returns>
64 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события.</param>
65 /// <param name="handler">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события.</param>
65 /// <remarks>Если ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Ρ‚ΠΎ ΠΎΠ½ΠΎ пСрСдаСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ ошибки, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹
66 /// <remarks>Если ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Ρ‚ΠΎ ΠΎΠ½ΠΎ пСрСдаСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ ошибки, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹
66 /// ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ связанному ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΡŽ</remarks>
67 /// ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ связанному ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΡŽ</remarks>
67 IPromise Cancelled(Action handler);
68 IPromise Cancelled(Action handler);
68
69
69 /// <summary>
70 /// <summary>
70 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π·Π°Π΄Π°Π½Π½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.
71 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π·Π°Π΄Π°Π½Π½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.
71 /// </summary>
72 /// </summary>
72 IPromise<T> Cast<T>();
73 IPromise<T> Cast<T>();
73
74
74 /// <summary>
75 /// <summary>
75 /// Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ с ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ΠΌ.
76 /// Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ с ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ΠΌ.
76 /// </summary>
77 /// </summary>
77 void Join();
78 void Join();
78 /// <summary>
79 /// <summary>
79 /// Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ с ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ΠΌ.
80 /// Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ с ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ΠΌ.
80 /// </summary>
81 /// </summary>
81 /// <param name="timeout">ВрСмя оТидания, ΠΏΠΎ Π΅Π³ΠΎ ΠΈΡΡ‚Π΅Ρ‡Π΅Π½ΠΈΡŽ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.</param>
82 /// <param name="timeout">ВрСмя оТидания, ΠΏΠΎ Π΅Π³ΠΎ ΠΈΡΡ‚Π΅Ρ‡Π΅Π½ΠΈΡŽ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.</param>
82 /// <exception cref="TimeoutException">ΠŸΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΎ врСмя оТидания.</exception>
83 /// <exception cref="TimeoutException">ΠŸΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΎ врСмя оТидания.</exception>
83 void Join(int timeout);
84 void Join(int timeout);
84
85
85 }
86 }
86 }
87 }
@@ -1,40 +1,40
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public interface IPromise<T> : IPromise {
4 public interface IPromise<T> : IPromise {
5
5
6 new T Join();
6 new T Join();
7
7
8 new T Join(int timeout);
8 new T Join(int timeout);
9
9
10 void Last(Action<T> success, Action<Exception> error, Action cancel);
10 void On(Action<T> success, Action<Exception> error, Action cancel);
11
11
12 void Last(Action<T> success, Action<Exception> error);
12 void On(Action<T> success, Action<Exception> error);
13
13
14 void Last(Action<T> success);
14 void On(Action<T> success);
15
15
16 IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel);
16 IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel);
17
17
18 IPromise<T> Then(Action<T> success, Func<Exception,T> error);
18 IPromise<T> Then(Action<T> success, Func<Exception,T> error);
19
19
20 IPromise<T> Then(Action<T> success);
20 IPromise<T> Then(Action<T> success);
21
21
22 IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error, Action cancel);
22 IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error, Action cancel);
23
23
24 IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error);
24 IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error);
25
25
26 IPromise<T2> Then<T2>(Func<T, T2> mapper);
26 IPromise<T2> Then<T2>(Func<T, T2> mapper);
27
27
28 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error, Action cancel);
28 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error, Action cancel);
29
29
30 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error);
30 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error);
31
31
32 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained);
32 IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained);
33
33
34 IPromise<T> Error(Func<Exception,T> error);
34 IPromise<T> Error(Func<Exception,T> error);
35
35
36 new IPromise<T> Cancelled(Action handler);
36 new IPromise<T> Cancelled(Action handler);
37
37
38 new IPromise<T> Anyway(Action handler);
38 new IPromise<T> Anyway(Action handler);
39 }
39 }
40 }
40 }
@@ -1,222 +1,223
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 </PropertyGroup>
10 </PropertyGroup>
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 <DebugSymbols>true</DebugSymbols>
12 <DebugSymbols>true</DebugSymbols>
13 <DebugType>full</DebugType>
13 <DebugType>full</DebugType>
14 <Optimize>false</Optimize>
14 <Optimize>false</Optimize>
15 <OutputPath>bin\Debug</OutputPath>
15 <OutputPath>bin\Debug</OutputPath>
16 <DefineConstants>TRACE;DEBUG;</DefineConstants>
16 <DefineConstants>TRACE;DEBUG;</DefineConstants>
17 <ErrorReport>prompt</ErrorReport>
17 <ErrorReport>prompt</ErrorReport>
18 <WarningLevel>4</WarningLevel>
18 <WarningLevel>4</WarningLevel>
19 <ConsolePause>false</ConsolePause>
19 <ConsolePause>false</ConsolePause>
20 <RunCodeAnalysis>true</RunCodeAnalysis>
20 <RunCodeAnalysis>true</RunCodeAnalysis>
21 </PropertyGroup>
21 </PropertyGroup>
22 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
22 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23 <DebugType>full</DebugType>
23 <DebugType>full</DebugType>
24 <Optimize>true</Optimize>
24 <Optimize>true</Optimize>
25 <OutputPath>bin\Release</OutputPath>
25 <OutputPath>bin\Release</OutputPath>
26 <ErrorReport>prompt</ErrorReport>
26 <ErrorReport>prompt</ErrorReport>
27 <WarningLevel>4</WarningLevel>
27 <WarningLevel>4</WarningLevel>
28 <ConsolePause>false</ConsolePause>
28 <ConsolePause>false</ConsolePause>
29 </PropertyGroup>
29 </PropertyGroup>
30 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
30 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
31 <DebugSymbols>true</DebugSymbols>
31 <DebugSymbols>true</DebugSymbols>
32 <DebugType>full</DebugType>
32 <DebugType>full</DebugType>
33 <Optimize>false</Optimize>
33 <Optimize>false</Optimize>
34 <OutputPath>bin\Debug</OutputPath>
34 <OutputPath>bin\Debug</OutputPath>
35 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
35 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
36 <ErrorReport>prompt</ErrorReport>
36 <ErrorReport>prompt</ErrorReport>
37 <WarningLevel>4</WarningLevel>
37 <WarningLevel>4</WarningLevel>
38 <RunCodeAnalysis>true</RunCodeAnalysis>
38 <RunCodeAnalysis>true</RunCodeAnalysis>
39 <ConsolePause>false</ConsolePause>
39 <ConsolePause>false</ConsolePause>
40 </PropertyGroup>
40 </PropertyGroup>
41 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
41 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
42 <Optimize>true</Optimize>
42 <Optimize>true</Optimize>
43 <OutputPath>bin\Release</OutputPath>
43 <OutputPath>bin\Release</OutputPath>
44 <ErrorReport>prompt</ErrorReport>
44 <ErrorReport>prompt</ErrorReport>
45 <WarningLevel>4</WarningLevel>
45 <WarningLevel>4</WarningLevel>
46 <ConsolePause>false</ConsolePause>
46 <ConsolePause>false</ConsolePause>
47 <DefineConstants>NET_4_5</DefineConstants>
47 <DefineConstants>NET_4_5</DefineConstants>
48 </PropertyGroup>
48 </PropertyGroup>
49 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
49 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
50 <DebugSymbols>true</DebugSymbols>
50 <DebugSymbols>true</DebugSymbols>
51 <DebugType>full</DebugType>
51 <DebugType>full</DebugType>
52 <Optimize>false</Optimize>
52 <Optimize>false</Optimize>
53 <OutputPath>bin\Debug</OutputPath>
53 <OutputPath>bin\Debug</OutputPath>
54 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
54 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
55 <ErrorReport>prompt</ErrorReport>
55 <ErrorReport>prompt</ErrorReport>
56 <WarningLevel>4</WarningLevel>
56 <WarningLevel>4</WarningLevel>
57 <RunCodeAnalysis>true</RunCodeAnalysis>
57 <RunCodeAnalysis>true</RunCodeAnalysis>
58 <ConsolePause>false</ConsolePause>
58 <ConsolePause>false</ConsolePause>
59 </PropertyGroup>
59 </PropertyGroup>
60 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
60 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
61 <Optimize>true</Optimize>
61 <Optimize>true</Optimize>
62 <OutputPath>bin\Release</OutputPath>
62 <OutputPath>bin\Release</OutputPath>
63 <DefineConstants>NET_4_5;MONO;</DefineConstants>
63 <DefineConstants>NET_4_5;MONO;</DefineConstants>
64 <ErrorReport>prompt</ErrorReport>
64 <ErrorReport>prompt</ErrorReport>
65 <WarningLevel>4</WarningLevel>
65 <WarningLevel>4</WarningLevel>
66 <ConsolePause>false</ConsolePause>
66 <ConsolePause>false</ConsolePause>
67 </PropertyGroup>
67 </PropertyGroup>
68 <ItemGroup>
68 <ItemGroup>
69 <Reference Include="System" />
69 <Reference Include="System" />
70 <Reference Include="System.Xml" />
70 <Reference Include="System.Xml" />
71 </ItemGroup>
71 </ItemGroup>
72 <ItemGroup>
72 <ItemGroup>
73 <Compile Include="Component.cs" />
73 <Compile Include="Component.cs" />
74 <Compile Include="CustomEqualityComparer.cs" />
74 <Compile Include="CustomEqualityComparer.cs" />
75 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
75 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
76 <Compile Include="Diagnostics\EventText.cs" />
76 <Compile Include="Diagnostics\EventText.cs" />
77 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
77 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
85 <Compile Include="Disposable.cs" />
85 <Compile Include="Disposable.cs" />
86 <Compile Include="ICancellable.cs" />
86 <Compile Include="ICancellable.cs" />
87 <Compile Include="IProgressHandler.cs" />
87 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressNotifier.cs" />
88 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IPromiseT.cs" />
89 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromise.cs" />
90 <Compile Include="IPromise.cs" />
91 <Compile Include="IServiceLocator.cs" />
91 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="ITaskController.cs" />
92 <Compile Include="ITaskController.cs" />
93 <Compile Include="JSON\JSONElementContext.cs" />
93 <Compile Include="JSON\JSONElementContext.cs" />
94 <Compile Include="JSON\JSONElementType.cs" />
94 <Compile Include="JSON\JSONElementType.cs" />
95 <Compile Include="JSON\JSONGrammar.cs" />
95 <Compile Include="JSON\JSONGrammar.cs" />
96 <Compile Include="JSON\JSONParser.cs" />
96 <Compile Include="JSON\JSONParser.cs" />
97 <Compile Include="JSON\JSONScanner.cs" />
97 <Compile Include="JSON\JSONScanner.cs" />
98 <Compile Include="JSON\JsonTokenType.cs" />
98 <Compile Include="JSON\JsonTokenType.cs" />
99 <Compile Include="JSON\JSONWriter.cs" />
99 <Compile Include="JSON\JSONWriter.cs" />
100 <Compile Include="JSON\JSONXmlReader.cs" />
100 <Compile Include="JSON\JSONXmlReader.cs" />
101 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
101 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
102 <Compile Include="JSON\StringTranslator.cs" />
102 <Compile Include="JSON\StringTranslator.cs" />
103 <Compile Include="Parallels\DispatchPool.cs" />
103 <Compile Include="Parallels\DispatchPool.cs" />
104 <Compile Include="Parallels\ArrayTraits.cs" />
104 <Compile Include="Parallels\ArrayTraits.cs" />
105 <Compile Include="Parallels\MTQueue.cs" />
105 <Compile Include="Parallels\MTQueue.cs" />
106 <Compile Include="Parallels\WorkerPool.cs" />
106 <Compile Include="Parallels\WorkerPool.cs" />
107 <Compile Include="Parsing\Alphabet.cs" />
107 <Compile Include="Parsing\Alphabet.cs" />
108 <Compile Include="Parsing\AlphabetBase.cs" />
108 <Compile Include="Parsing\AlphabetBase.cs" />
109 <Compile Include="Parsing\AltToken.cs" />
109 <Compile Include="Parsing\AltToken.cs" />
110 <Compile Include="Parsing\BinaryToken.cs" />
110 <Compile Include="Parsing\BinaryToken.cs" />
111 <Compile Include="Parsing\CatToken.cs" />
111 <Compile Include="Parsing\CatToken.cs" />
112 <Compile Include="Parsing\CDFADefinition.cs" />
112 <Compile Include="Parsing\CDFADefinition.cs" />
113 <Compile Include="Parsing\DFABuilder.cs" />
113 <Compile Include="Parsing\DFABuilder.cs" />
114 <Compile Include="Parsing\DFADefinitionBase.cs" />
114 <Compile Include="Parsing\DFADefinitionBase.cs" />
115 <Compile Include="Parsing\DFAStateDescriptor.cs" />
115 <Compile Include="Parsing\DFAStateDescriptor.cs" />
116 <Compile Include="Parsing\DFAutomaton.cs" />
116 <Compile Include="Parsing\DFAutomaton.cs" />
117 <Compile Include="Parsing\EDFADefinition.cs" />
117 <Compile Include="Parsing\EDFADefinition.cs" />
118 <Compile Include="Parsing\EmptyToken.cs" />
118 <Compile Include="Parsing\EmptyToken.cs" />
119 <Compile Include="Parsing\EndToken.cs" />
119 <Compile Include="Parsing\EndToken.cs" />
120 <Compile Include="Parsing\EnumAlphabet.cs" />
120 <Compile Include="Parsing\EnumAlphabet.cs" />
121 <Compile Include="Parsing\Grammar.cs" />
121 <Compile Include="Parsing\Grammar.cs" />
122 <Compile Include="Parsing\IAlphabet.cs" />
122 <Compile Include="Parsing\IAlphabet.cs" />
123 <Compile Include="Parsing\IDFADefinition.cs" />
123 <Compile Include="Parsing\IDFADefinition.cs" />
124 <Compile Include="Parsing\IVisitor.cs" />
124 <Compile Include="Parsing\IVisitor.cs" />
125 <Compile Include="Parsing\ParserException.cs" />
125 <Compile Include="Parsing\ParserException.cs" />
126 <Compile Include="Parsing\Scanner.cs" />
126 <Compile Include="Parsing\Scanner.cs" />
127 <Compile Include="Parsing\StarToken.cs" />
127 <Compile Include="Parsing\StarToken.cs" />
128 <Compile Include="Parsing\SymbolToken.cs" />
128 <Compile Include="Parsing\SymbolToken.cs" />
129 <Compile Include="Parsing\Token.cs" />
129 <Compile Include="Parsing\Token.cs" />
130 <Compile Include="SafePool.cs" />
130 <Compile Include="SafePool.cs" />
131 <Compile Include="ServiceLocator.cs" />
131 <Compile Include="ServiceLocator.cs" />
132 <Compile Include="TaskController.cs" />
132 <Compile Include="TaskController.cs" />
133 <Compile Include="ProgressInitEventArgs.cs" />
133 <Compile Include="ProgressInitEventArgs.cs" />
134 <Compile Include="Properties\AssemblyInfo.cs" />
134 <Compile Include="Properties\AssemblyInfo.cs" />
135 <Compile Include="Promise.cs" />
135 <Compile Include="Promise.cs" />
136 <Compile Include="Parallels\AsyncPool.cs" />
136 <Compile Include="Parallels\AsyncPool.cs" />
137 <Compile Include="Safe.cs" />
137 <Compile Include="Safe.cs" />
138 <Compile Include="ValueEventArgs.cs" />
138 <Compile Include="ValueEventArgs.cs" />
139 <Compile Include="PromiseExtensions.cs" />
139 <Compile Include="PromiseExtensions.cs" />
140 <Compile Include="TransientPromiseException.cs" />
140 <Compile Include="TransientPromiseException.cs" />
141 <Compile Include="SyncContextPromise.cs" />
141 <Compile Include="SyncContextPromise.cs" />
142 <Compile Include="ObjectPool.cs" />
142 <Compile Include="ObjectPool.cs" />
143 <Compile Include="Diagnostics\OperationContext.cs" />
143 <Compile Include="Diagnostics\OperationContext.cs" />
144 <Compile Include="Diagnostics\TraceContext.cs" />
144 <Compile Include="Diagnostics\TraceContext.cs" />
145 <Compile Include="Diagnostics\LogEventArgs.cs" />
145 <Compile Include="Diagnostics\LogEventArgs.cs" />
146 <Compile Include="Diagnostics\LogEventArgsT.cs" />
146 <Compile Include="Diagnostics\LogEventArgsT.cs" />
147 <Compile Include="Diagnostics\Extensions.cs" />
147 <Compile Include="Diagnostics\Extensions.cs" />
148 <Compile Include="IComponentContainer.cs" />
148 <Compile Include="IComponentContainer.cs" />
149 <Compile Include="MTComponentContainer.cs" />
149 <Compile Include="MTComponentContainer.cs" />
150 <Compile Include="PromiseEventType.cs" />
150 </ItemGroup>
151 </ItemGroup>
151 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
152 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
152 <ItemGroup />
153 <ItemGroup />
153 <ProjectExtensions>
154 <ProjectExtensions>
154 <MonoDevelop>
155 <MonoDevelop>
155 <Properties>
156 <Properties>
156 <Policies>
157 <Policies>
157 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
158 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
158 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
159 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
159 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
160 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
160 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
161 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
161 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
162 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
162 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
163 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
163 <NameConventionPolicy>
164 <NameConventionPolicy>
164 <Rules>
165 <Rules>
165 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
166 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
166 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
167 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
167 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
168 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
168 <RequiredPrefixes>
169 <RequiredPrefixes>
169 <String>I</String>
170 <String>I</String>
170 </RequiredPrefixes>
171 </RequiredPrefixes>
171 </NamingRule>
172 </NamingRule>
172 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
173 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
173 <RequiredSuffixes>
174 <RequiredSuffixes>
174 <String>Attribute</String>
175 <String>Attribute</String>
175 </RequiredSuffixes>
176 </RequiredSuffixes>
176 </NamingRule>
177 </NamingRule>
177 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
178 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
178 <RequiredSuffixes>
179 <RequiredSuffixes>
179 <String>EventArgs</String>
180 <String>EventArgs</String>
180 </RequiredSuffixes>
181 </RequiredSuffixes>
181 </NamingRule>
182 </NamingRule>
182 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
183 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
183 <RequiredSuffixes>
184 <RequiredSuffixes>
184 <String>Exception</String>
185 <String>Exception</String>
185 </RequiredSuffixes>
186 </RequiredSuffixes>
186 </NamingRule>
187 </NamingRule>
187 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
188 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
188 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
189 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
189 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
190 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
190 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
191 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
191 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
192 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
192 <RequiredPrefixes>
193 <RequiredPrefixes>
193 <String>m_</String>
194 <String>m_</String>
194 </RequiredPrefixes>
195 </RequiredPrefixes>
195 </NamingRule>
196 </NamingRule>
196 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
197 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
197 <RequiredPrefixes>
198 <RequiredPrefixes>
198 <String>_</String>
199 <String>_</String>
199 </RequiredPrefixes>
200 </RequiredPrefixes>
200 </NamingRule>
201 </NamingRule>
201 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
202 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
202 <RequiredPrefixes>
203 <RequiredPrefixes>
203 <String>m_</String>
204 <String>m_</String>
204 </RequiredPrefixes>
205 </RequiredPrefixes>
205 </NamingRule>
206 </NamingRule>
206 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
207 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
207 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
208 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
208 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
209 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
209 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
211 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
211 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
212 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
212 <RequiredPrefixes>
213 <RequiredPrefixes>
213 <String>T</String>
214 <String>T</String>
214 </RequiredPrefixes>
215 </RequiredPrefixes>
215 </NamingRule>
216 </NamingRule>
216 </Rules>
217 </Rules>
217 </NameConventionPolicy>
218 </NameConventionPolicy>
218 </Policies>
219 </Policies>
219 </Properties>
220 </Properties>
220 </MonoDevelop>
221 </MonoDevelop>
221 </ProjectExtensions>
222 </ProjectExtensions>
222 </Project> No newline at end of file
223 </Project>
@@ -1,207 +1,207
1 using Implab.Diagnostics;
1 using Implab.Diagnostics;
2 using System;
2 using System;
3 using System.Diagnostics;
3 using System.Diagnostics;
4 using System.Threading;
4 using System.Threading;
5
5
6 namespace Implab.Parallels {
6 namespace Implab.Parallels {
7 public static class ArrayTraits {
7 public static class ArrayTraits {
8 class ArrayIterator<TSrc> : DispatchPool<int> {
8 class ArrayIterator<TSrc> : DispatchPool<int> {
9 readonly Action<TSrc> m_action;
9 readonly Action<TSrc> m_action;
10 readonly TSrc[] m_source;
10 readonly TSrc[] m_source;
11 readonly Promise<int> m_promise = new Promise<int>();
11 readonly Promise<int> m_promise = new Promise<int>();
12 readonly LogicalOperation m_logicalOperation;
12 readonly LogicalOperation m_logicalOperation;
13
13
14 int m_pending;
14 int m_pending;
15 int m_next;
15 int m_next;
16
16
17 public ArrayIterator(TSrc[] source, Action<TSrc> action, int threads)
17 public ArrayIterator(TSrc[] source, Action<TSrc> action, int threads)
18 : base(threads) {
18 : base(threads) {
19
19
20 Debug.Assert(source != null);
20 Debug.Assert(source != null);
21 Debug.Assert(action != null);
21 Debug.Assert(action != null);
22
22
23 m_logicalOperation = TraceContext.Instance.CurrentOperation;
23 m_logicalOperation = TraceContext.Instance.CurrentOperation;
24 m_next = 0;
24 m_next = 0;
25 m_source = source;
25 m_source = source;
26 m_pending = source.Length;
26 m_pending = source.Length;
27 m_action = action;
27 m_action = action;
28
28
29 m_promise.Anyway(Dispose);
29 m_promise.Anyway(Dispose);
30
30
31 InitPool();
31 InitPool();
32 }
32 }
33
33
34 public Promise<int> Promise {
34 public Promise<int> Promise {
35 get {
35 get {
36 return m_promise;
36 return m_promise;
37 }
37 }
38 }
38 }
39
39
40 protected override void Worker() {
40 protected override void Worker() {
41 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation, false);
41 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation, false);
42 try {
42 try {
43 base.Worker();
43 base.Worker();
44 } finally {
44 } finally {
45 TraceContext.Instance.Leave();
45 TraceContext.Instance.Leave();
46 }
46 }
47 }
47 }
48
48
49 protected override bool TryDequeue(out int unit) {
49 protected override bool TryDequeue(out int unit) {
50 unit = Interlocked.Increment(ref m_next) - 1;
50 unit = Interlocked.Increment(ref m_next) - 1;
51 return unit < m_source.Length;
51 return unit < m_source.Length;
52 }
52 }
53
53
54 protected override void InvokeUnit(int unit) {
54 protected override void InvokeUnit(int unit) {
55 try {
55 try {
56 m_action(m_source[unit]);
56 m_action(m_source[unit]);
57 var pending = Interlocked.Decrement(ref m_pending);
57 var pending = Interlocked.Decrement(ref m_pending);
58 if (pending == 0)
58 if (pending == 0)
59 m_promise.Resolve(m_source.Length);
59 m_promise.Resolve(m_source.Length);
60 } catch (Exception e) {
60 } catch (Exception e) {
61 m_promise.Reject(e);
61 m_promise.Reject(e);
62 }
62 }
63 }
63 }
64 }
64 }
65
65
66 class ArrayMapper<TSrc, TDst>: DispatchPool<int> {
66 class ArrayMapper<TSrc, TDst>: DispatchPool<int> {
67 readonly Func<TSrc, TDst> m_transform;
67 readonly Func<TSrc, TDst> m_transform;
68 readonly TSrc[] m_source;
68 readonly TSrc[] m_source;
69 readonly TDst[] m_dest;
69 readonly TDst[] m_dest;
70 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
70 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
71 readonly LogicalOperation m_logicalOperation;
71 readonly LogicalOperation m_logicalOperation;
72
72
73 int m_pending;
73 int m_pending;
74 int m_next;
74 int m_next;
75
75
76 public ArrayMapper(TSrc[] source, Func<TSrc, TDst> transform, int threads)
76 public ArrayMapper(TSrc[] source, Func<TSrc, TDst> transform, int threads)
77 : base(threads) {
77 : base(threads) {
78
78
79 Debug.Assert (source != null);
79 Debug.Assert (source != null);
80 Debug.Assert( transform != null);
80 Debug.Assert( transform != null);
81
81
82 m_next = 0;
82 m_next = 0;
83 m_source = source;
83 m_source = source;
84 m_dest = new TDst[source.Length];
84 m_dest = new TDst[source.Length];
85 m_pending = source.Length;
85 m_pending = source.Length;
86 m_transform = transform;
86 m_transform = transform;
87 m_logicalOperation = TraceContext.Instance.CurrentOperation;
87 m_logicalOperation = TraceContext.Instance.CurrentOperation;
88
88
89 m_promise.Anyway(Dispose);
89 m_promise.Anyway(Dispose);
90
90
91 InitPool();
91 InitPool();
92 }
92 }
93
93
94 public Promise<TDst[]> Promise {
94 public Promise<TDst[]> Promise {
95 get {
95 get {
96 return m_promise;
96 return m_promise;
97 }
97 }
98 }
98 }
99
99
100 protected override void Worker() {
100 protected override void Worker() {
101 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation,false);
101 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation,false);
102 try {
102 try {
103 base.Worker();
103 base.Worker();
104 } finally {
104 } finally {
105 TraceContext.Instance.Leave();
105 TraceContext.Instance.Leave();
106 }
106 }
107 }
107 }
108
108
109 protected override bool TryDequeue(out int unit) {
109 protected override bool TryDequeue(out int unit) {
110 unit = Interlocked.Increment(ref m_next) - 1;
110 unit = Interlocked.Increment(ref m_next) - 1;
111 return unit < m_source.Length;
111 return unit < m_source.Length;
112 }
112 }
113
113
114 protected override void InvokeUnit(int unit) {
114 protected override void InvokeUnit(int unit) {
115 try {
115 try {
116 m_dest[unit] = m_transform(m_source[unit]);
116 m_dest[unit] = m_transform(m_source[unit]);
117 var pending = Interlocked.Decrement(ref m_pending);
117 var pending = Interlocked.Decrement(ref m_pending);
118 if (pending == 0)
118 if (pending == 0)
119 m_promise.Resolve(m_dest);
119 m_promise.Resolve(m_dest);
120 } catch (Exception e) {
120 } catch (Exception e) {
121 m_promise.Reject(e);
121 m_promise.Reject(e);
122 }
122 }
123 }
123 }
124 }
124 }
125
125
126 public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) {
126 public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) {
127 if (source == null)
127 if (source == null)
128 throw new ArgumentNullException("source");
128 throw new ArgumentNullException("source");
129 if (transform == null)
129 if (transform == null)
130 throw new ArgumentNullException("transform");
130 throw new ArgumentNullException("transform");
131
131
132 var mapper = new ArrayMapper<TSrc, TDst>(source, transform, threads);
132 var mapper = new ArrayMapper<TSrc, TDst>(source, transform, threads);
133 return mapper.Promise;
133 return mapper.Promise;
134 }
134 }
135
135
136 public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) {
136 public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) {
137 if (source == null)
137 if (source == null)
138 throw new ArgumentNullException("source");
138 throw new ArgumentNullException("source");
139 if (action == null)
139 if (action == null)
140 throw new ArgumentNullException("action");
140 throw new ArgumentNullException("action");
141
141
142 var iter = new ArrayIterator<TSrc>(source, action, threads);
142 var iter = new ArrayIterator<TSrc>(source, action, threads);
143 return iter.Promise;
143 return iter.Promise;
144 }
144 }
145
145
146 public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, Func<TSrc, IPromise<TDst>> transform, int threads) {
146 public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, Func<TSrc, IPromise<TDst>> transform, int threads) {
147 if (source == null)
147 if (source == null)
148 throw new ArgumentNullException("source");
148 throw new ArgumentNullException("source");
149 if (transform == null)
149 if (transform == null)
150 throw new ArgumentNullException("transform");
150 throw new ArgumentNullException("transform");
151 if (threads <= 0)
151 if (threads <= 0)
152 throw new ArgumentOutOfRangeException("threads","Threads number must be greater then zero");
152 throw new ArgumentOutOfRangeException("threads","Threads number must be greater then zero");
153
153
154 if (source.Length == 0)
154 if (source.Length == 0)
155 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
155 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
156
156
157 var promise = new Promise<TDst[]>();
157 var promise = new Promise<TDst[]>();
158 var res = new TDst[source.Length];
158 var res = new TDst[source.Length];
159 var pending = source.Length;
159 var pending = source.Length;
160
160
161 object locker = new object();
161 object locker = new object();
162 int slots = threads;
162 int slots = threads;
163
163
164 // Analysis disable AccessToDisposedClosure
164 // Analysis disable AccessToDisposedClosure
165 AsyncPool.InvokeNewThread(() => {
165 AsyncPool.InvokeNewThread(() => {
166 for (int i = 0; i < source.Length; i++) {
166 for (int i = 0; i < source.Length; i++) {
167 if(promise.IsResolved)
167 if(promise.IsResolved)
168 break; // stop processing in case of error or cancellation
168 break; // stop processing in case of error or cancellation
169 var idx = i;
169 var idx = i;
170
170
171 if (Interlocked.Decrement(ref slots) < 0) {
171 if (Interlocked.Decrement(ref slots) < 0) {
172 lock(locker) {
172 lock(locker) {
173 while(slots < 0)
173 while(slots < 0)
174 Monitor.Wait(locker);
174 Monitor.Wait(locker);
175 }
175 }
176 }
176 }
177
177
178 try {
178 try {
179 transform(source[i])
179 transform(source[i])
180 .Anyway(() => {
180 .Anyway(() => {
181 Interlocked.Increment(ref slots);
181 Interlocked.Increment(ref slots);
182 lock (locker) {
182 lock (locker) {
183 Monitor.Pulse(locker);
183 Monitor.Pulse(locker);
184 }
184 }
185 })
185 })
186 .Last(
186 .On(
187 x => {
187 x => {
188 res[idx] = x;
188 res[idx] = x;
189 var left = Interlocked.Decrement(ref pending);
189 var left = Interlocked.Decrement(ref pending);
190 if (left == 0)
190 if (left == 0)
191 promise.Resolve(res);
191 promise.Resolve(res);
192 },
192 },
193 promise.Reject
193 promise.Reject
194 );
194 );
195
195
196 } catch (Exception e) {
196 } catch (Exception e) {
197 promise.Reject(e);
197 promise.Reject(e);
198 }
198 }
199 }
199 }
200 return 0;
200 return 0;
201 });
201 });
202
202
203 return promise;
203 return promise;
204 }
204 }
205
205
206 }
206 }
207 }
207 }
@@ -1,908 +1,932
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 struct HandlerDescriptor {
45 protected struct HandlerDescriptor {
46 public Action<T> resultHandler;
46 public Action<T> resultHandler;
47 public Func<Exception,T> errorHandler;
47 public Func<Exception,T> errorHandler;
48 public Action cancellHandler;
48 public Action cancellHandler;
49 public Promise<T> medium;
49 public Promise<T> medium;
50
50
51 public void Resolve(T result) {
51 public void Resolve(T result) {
52 if (resultHandler != null) {
52 if (resultHandler != null) {
53 try {
53 try {
54 resultHandler(result);
54 resultHandler(result);
55 } catch (Exception e) {
55 } catch (Exception e) {
56 Reject(e);
56 Reject(e);
57 return;
57 return;
58 }
58 }
59 }
59 }
60 if (medium != null)
60 if (medium != null)
61 medium.Resolve(result);
61 medium.Resolve(result);
62 }
62 }
63
63
64 public void Reject(Exception err) {
64 public void Reject(Exception err) {
65 if (errorHandler != null) {
65 if (errorHandler != null) {
66 try {
66 try {
67 var res = errorHandler(err);
67 var res = errorHandler(err);
68 if (medium != null)
68 if (medium != null)
69 medium.Resolve(res);
69 medium.Resolve(res);
70 /*} catch (TransientPromiseException err2) {
70 /*} catch (TransientPromiseException err2) {
71 if (medium != null)
71 if (medium != null)
72 medium.Reject(err2.InnerException);*/
72 medium.Reject(err2.InnerException);*/
73 } catch (Exception err2) {
73 } catch (Exception err2) {
74 if (medium != null)
74 if (medium != null)
75 medium.Reject(err2);
75 medium.Reject(err2);
76 }
76 }
77 } else if (medium != null)
77 } else if (medium != null)
78 medium.Reject(err);
78 medium.Reject(err);
79 }
79 }
80
80
81 public void Cancel() {
81 public void Cancel() {
82 if (cancellHandler != null) {
82 if (cancellHandler != null) {
83 try {
83 try {
84 cancellHandler();
84 cancellHandler();
85 } catch (Exception err) {
85 } catch (Exception err) {
86 Reject(err);
86 Reject(err);
87 return;
87 return;
88 }
88 }
89 }
89 }
90 if (medium != null)
90 if (medium != null)
91 medium.Cancel();
91 medium.Cancel();
92 }
92 }
93 }
93 }
94
94
95 const int UNRESOLVED_SATE = 0;
95 const int UNRESOLVED_SATE = 0;
96 const int TRANSITIONAL_STATE = 1;
96 const int TRANSITIONAL_STATE = 1;
97 const int SUCCEEDED_STATE = 2;
97 const int SUCCEEDED_STATE = 2;
98 const int REJECTED_STATE = 3;
98 const int REJECTED_STATE = 3;
99 const int CANCELLED_STATE = 4;
99 const int CANCELLED_STATE = 4;
100
100
101 int m_childrenCount;
101 int m_childrenCount;
102 int m_state;
102 int m_state;
103 T m_result;
103 T m_result;
104 Exception m_error;
104 Exception m_error;
105
105
106 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
106 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
107
107
108 public Promise() {
108 public Promise() {
109 }
109 }
110
110
111 public Promise(IPromise parent) {
111 public Promise(IPromise parent) {
112 if (parent != null)
112 if (parent != null)
113 AddHandler(
113 AddHandler(
114 null,
114 null,
115 null,
115 null,
116 () => {
116 () => {
117 if (parent.IsExclusive)
117 if (parent.IsExclusive)
118 parent.Cancel();
118 parent.Cancel();
119 },
119 },
120 null
120 null,
121 false
121 );
122 );
122 }
123 }
123
124
124 bool BeginTransit() {
125 bool BeginTransit() {
125 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
126 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
126 }
127 }
127
128
128 void CompleteTransit(int state) {
129 void CompleteTransit(int state) {
129 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
130 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
130 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
131 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
131 }
132 }
132
133
133 void WaitTransition() {
134 void WaitTransition() {
134 while (m_state == TRANSITIONAL_STATE) {
135 while (m_state == TRANSITIONAL_STATE) {
135 Thread.MemoryBarrier();
136 Thread.MemoryBarrier();
136 }
137 }
137 }
138 }
138
139
139 public bool IsResolved {
140 public bool IsResolved {
140 get {
141 get {
141 Thread.MemoryBarrier();
142 Thread.MemoryBarrier();
142 return m_state > 1;
143 return m_state > 1;
143 }
144 }
144 }
145 }
145
146
146 public bool IsCancelled {
147 public bool IsCancelled {
147 get {
148 get {
148 Thread.MemoryBarrier();
149 Thread.MemoryBarrier();
149 return m_state == CANCELLED_STATE;
150 return m_state == CANCELLED_STATE;
150 }
151 }
151 }
152 }
152
153
153 public Type PromiseType {
154 public Type PromiseType {
154 get { return typeof(T); }
155 get { return typeof(T); }
155 }
156 }
156
157
157 /// <summary>
158 /// <summary>
158 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ.
159 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ.
159 /// </summary>
160 /// </summary>
160 /// <param name="result">Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния.</param>
161 /// <param name="result">Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния.</param>
161 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
162 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
162 public void Resolve(T result) {
163 public void Resolve(T result) {
163 if (BeginTransit()) {
164 if (BeginTransit()) {
164 m_result = result;
165 m_result = result;
165 CompleteTransit(SUCCEEDED_STATE);
166 CompleteTransit(SUCCEEDED_STATE);
166 OnStateChanged();
167 OnStateChanged();
167 } else {
168 } else {
168 WaitTransition();
169 WaitTransition();
169 if (m_state != CANCELLED_STATE)
170 if (m_state != CANCELLED_STATE)
170 throw new InvalidOperationException("The promise is already resolved");
171 throw new InvalidOperationException("The promise is already resolved");
171 }
172 }
172 }
173 }
173
174
174 /// <summary>
175 /// <summary>
175 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
176 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
176 /// </summary>
177 /// </summary>
177 /// <remarks>
178 /// <remarks>
178 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
179 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
179 /// </remarks>
180 /// </remarks>
180 public void Resolve() {
181 public void Resolve() {
181 Resolve(default(T));
182 Resolve(default(T));
182 }
183 }
183
184
184 /// <summary>
185 /// <summary>
185 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
186 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
186 /// </summary>
187 /// </summary>
187 /// <remarks>
188 /// <remarks>
188 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
189 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
189 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
190 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
190 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
191 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
191 /// </remarks>
192 /// </remarks>
192 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
193 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
193 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
194 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
194 public void Reject(Exception error) {
195 public void Reject(Exception error) {
195 if (BeginTransit()) {
196 if (BeginTransit()) {
196 m_error = error is TransientPromiseException ? error.InnerException : error;
197 m_error = error is TransientPromiseException ? error.InnerException : error;
197 CompleteTransit(REJECTED_STATE);
198 CompleteTransit(REJECTED_STATE);
198 OnStateChanged();
199 OnStateChanged();
199 } else {
200 } else {
200 WaitTransition();
201 WaitTransition();
201 if (m_state == SUCCEEDED_STATE)
202 if (m_state == SUCCEEDED_STATE)
202 throw new InvalidOperationException("The promise is already resolved");
203 throw new InvalidOperationException("The promise is already resolved");
203 }
204 }
204 }
205 }
205
206
206 /// <summary>
207 /// <summary>
207 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
208 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
208 /// </summary>
209 /// </summary>
209 /// <remarks>Для опрСдСлСния Π±Ρ‹Π»Π° Π»ΠΈ опСрация ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π° слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свойство <see cref="IsCancelled"/>.</remarks>
210 /// <remarks>Для опрСдСлСния Π±Ρ‹Π»Π° Π»ΠΈ опСрация ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π° слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свойство <see cref="IsCancelled"/>.</remarks>
210 public void Cancel() {
211 public void Cancel() {
211 if (BeginTransit()) {
212 if (BeginTransit()) {
212 CompleteTransit(CANCELLED_STATE);
213 CompleteTransit(CANCELLED_STATE);
213 OnStateChanged();
214 OnStateChanged();
214 }
215 }
215 }
216 }
216
217
217 public IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel) {
218 public IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel) {
218 if (success == null && error == null && cancel == null)
219 if (success == null && error == null && cancel == null)
219 return this;
220 return this;
220
221
221 var medium = new Promise<T>(this);
222 var medium = new Promise<T>(this);
222
223
223 AddHandler(success, error, cancel, medium);
224 AddHandler(success, error, cancel, medium, true);
224
225
225 return medium;
226 return medium;
226 }
227 }
227
228
228 /// <summary>
229 /// <summary>
229 /// Adds new handlers to this promise.
230 /// Adds new handlers to this promise.
230 /// </summary>
231 /// </summary>
231 /// <param name="success">The handler of the successfully completed operation.
232 /// <param name="success">The handler of the successfully completed operation.
232 /// This handler will recieve an operation result as a parameter.</param>
233 /// This handler will recieve an operation result as a parameter.</param>
233 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
234 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
234 /// <returns>The new promise chained to this one.</returns>
235 /// <returns>The new promise chained to this one.</returns>
235 public IPromise<T> Then(Action<T> success, Func<Exception,T> error) {
236 public IPromise<T> Then(Action<T> success, Func<Exception,T> error) {
236 if (success == null && error == null)
237 if (success == null && error == null)
237 return this;
238 return this;
238
239
239 var medium = new Promise<T>(this);
240 var medium = new Promise<T>(this);
240
241
241 AddHandler(success, error, null, medium);
242 AddHandler(success, error, null, medium, true);
242
243
243 return medium;
244 return medium;
244 }
245 }
245
246
246
247
247
248
248
249
249 public IPromise<T> Then(Action<T> success) {
250 public IPromise<T> Then(Action<T> success) {
250 if (success == null)
251 if (success == null)
251 return this;
252 return this;
252
253
253 var medium = new Promise<T>(this);
254 var medium = new Promise<T>(this);
254
255
255 AddHandler(success, null, null, medium);
256 AddHandler(success, null, null, medium, true);
256
257
257 return medium;
258 return medium;
258 }
259 }
259
260
260 /// <summary>
261 /// <summary>
261 /// ПослСдний ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
262 /// ПослСдний ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
262 /// </summary>
263 /// </summary>
263 /// <param name="success"></param>
264 /// <param name="success"></param>
264 /// <param name="error"></param>
265 /// <param name="error"></param>
265 /// <param name="cancel"></param>
266 /// <param name="cancel"></param>
266 /// <remarks>
267 /// <remarks>
267 /// <para>
268 /// <para>
268 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ создаСт связанного с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ обСщания ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для окончания
269 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ создаСт связанного с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ обСщания ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для окончания
269 /// фсинхронной Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ.
270 /// фсинхронной Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ.
270 /// </para>
271 /// </para>
271 /// <para>
272 /// <para>
272 /// Если Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ нСсколько Ρ€Π°Π·, Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, Ρ‚ΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°
273 /// Если Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ нСсколько Ρ€Π°Π·, Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, Ρ‚ΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°
273 /// Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠΉ <see cref="IsExclusive"/> ΠΈ, ΠΊΠ°ΠΊ слСдствиС, Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ΠΎΡ‚ΠΌΠ΅Π½Π°
274 /// Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠΉ <see cref="IsExclusive"/> ΠΈ, ΠΊΠ°ΠΊ слСдствиС, Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ΠΎΡ‚ΠΌΠ΅Π½Π°
274 /// всСй Ρ†Π΅ΠΏΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ снизу (с самого послСднСго обСщания).
275 /// всСй Ρ†Π΅ΠΏΠΈ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ снизу (с самого послСднСго обСщания).
275 /// </para>
276 /// </para>
276 /// </remarks>
277 /// </remarks>
277 public void Last(Action<T> success, Action<Exception> error, Action cancel) {
278 public void On(Action<T> success, Action<Exception> error, Action cancel) {
278 if (success == null && error == null && cancel == null)
279 if (success == null && error == null && cancel == null)
279 return;
280 return;
280
281
281 Func<Exception,T> errorHandler = null;
282 Func<Exception,T> errorHandler = null;
282 if (error != null)
283 if (error != null)
283 errorHandler = err => {
284 errorHandler = err => {
284 error(err);
285 error(err);
285 return default(T);
286 return default(T);
286 };
287 };
287 AddHandler(success, errorHandler, cancel, null);
288 AddHandler(success, errorHandler, cancel, null, false);
289 }
290
291 public void On(Action<T> success, Action<Exception> error) {
292 On(success, error, null);
293 }
294
295 public void On(Action<T> success) {
296 On(success, null, null);
288 }
297 }
289
298
290 public void Last(Action<T> success, Action<Exception> error) {
299 public void On(Action handler, PromiseEventType events) {
291 Last(success, error, null);
300 Safe.ArgumentNotNull(handler, "handler");
292 }
293
301
294 public void Last(Action<T> success) {
302 Action<T> success = events.HasFlag(PromiseEventType.Success) ? new Action<T>(x => handler()) : null;
295 Last(success, null, null);
303 Func<Exception,T> error = events.HasFlag(PromiseEventType.Error) ? new Func<Exception,T>(e => {
304 handler();
305 return default(T);
306 }) : null;
307 Action cancel = events.HasFlag(PromiseEventType.Cancelled) ? handler : null;
308
309 AddHandler(success, error, cancel, null, false);
296 }
310 }
297
311
298 public IPromise Error(Action<Exception> error) {
312 public IPromise Error(Action<Exception> error) {
299 if (error == null)
313 if (error == null)
300 return this;
314 return this;
301
315
302 var medium = new Promise<T>(this);
316 var medium = new Promise<T>(this);
303
317
304 AddHandler(
318 AddHandler(
305 null,
319 null,
306 e => {
320 e => {
307 error(e);
321 error(e);
308 return default(T);
322 return default(T);
309 },
323 },
310 null,
324 null,
311 medium
325 medium,
326 true
312 );
327 );
313
328
314 return medium;
329 return medium;
315 }
330 }
316
331
317 /// <summary>
332 /// <summary>
318 /// Handles error and allows to keep the promise.
333 /// Handles error and allows to keep the promise.
319 /// </summary>
334 /// </summary>
320 /// <remarks>
335 /// <remarks>
321 /// If the specified handler throws an exception, this exception will be used to reject the promise.
336 /// If the specified handler throws an exception, this exception will be used to reject the promise.
322 /// </remarks>
337 /// </remarks>
323 /// <param name="handler">The error handler which returns the result of the promise.</param>
338 /// <param name="handler">The error handler which returns the result of the promise.</param>
324 /// <returns>New promise.</returns>
339 /// <returns>New promise.</returns>
325 public IPromise<T> Error(Func<Exception,T> handler) {
340 public IPromise<T> Error(Func<Exception,T> handler) {
326 if (handler == null)
341 if (handler == null)
327 return this;
342 return this;
328
343
329 var medium = new Promise<T>(this);
344 var medium = new Promise<T>(this);
330
345
331 AddHandler(null, handler, null, medium);
346 AddHandler(null, handler, null, medium, true);
332
347
333 return medium;
348 return medium;
334 }
349 }
335
350
336 /// <summary>
351 /// <summary>
337 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.
352 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.
338 /// </summary>
353 /// </summary>
339 /// <typeparam name="TNew">Новый Ρ‚ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.</typeparam>
354 /// <typeparam name="TNew">Новый Ρ‚ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.</typeparam>
340 /// <param name="mapper">ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.</param>
355 /// <param name="mapper">ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.</param>
341 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
356 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
342 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
357 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
343 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ исходного обСщания.</returns>
358 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ исходного обСщания.</returns>
344 /// <param name = "cancel"></param>
359 /// <param name = "cancel"></param>
345 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error, Action cancel) {
360 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error, Action cancel) {
346 Safe.ArgumentNotNull(mapper, "mapper");
361 Safe.ArgumentNotNull(mapper, "mapper");
347
362
348 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
363 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
349 var medium = new Promise<TNew>(this);
364 var medium = new Promise<TNew>(this);
350
365
351 Action<T> resultHandler = result => medium.Resolve(mapper(result));
366 Action<T> resultHandler = result => medium.Resolve(mapper(result));
352 Func<Exception,T> errorHandler;
367 Func<Exception,T> errorHandler;
353 if (error != null)
368 if (error != null)
354 errorHandler = e => {
369 errorHandler = e => {
355 try {
370 try {
356 medium.Resolve(error(e));
371 medium.Resolve(error(e));
357 } catch (Exception e2) {
372 } catch (Exception e2) {
358 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
373 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
359 medium.Reject(e2);
374 medium.Reject(e2);
360 }
375 }
361 return default(T);
376 return default(T);
362 };
377 };
363 else
378 else
364 errorHandler = e => {
379 errorHandler = e => {
365 medium.Reject(e);
380 medium.Reject(e);
366 return default(T);
381 return default(T);
367 };
382 };
368
383
369 Action cancelHandler;
384 Action cancelHandler;
370 if (cancel != null)
385 if (cancel != null)
371 cancelHandler = () => {
386 cancelHandler = () => {
372 cancel();
387 cancel();
373 medium.Cancel();
388 medium.Cancel();
374 };
389 };
375 else
390 else
376 cancelHandler = medium.Cancel;
391 cancelHandler = medium.Cancel;
377
392
378
393
379 AddHandler(
394 AddHandler(
380 resultHandler,
395 resultHandler,
381 errorHandler,
396 errorHandler,
382 cancelHandler,
397 cancelHandler,
383 null
398 null,
399 true
384 );
400 );
385
401
386 return medium;
402 return medium;
387 }
403 }
388
404
389 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error) {
405 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error) {
390 return Then(mapper, error, null);
406 return Then(mapper, error, null);
391 }
407 }
392
408
393 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper) {
409 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper) {
394 return Then(mapper, null, null);
410 return Then(mapper, null, null);
395 }
411 }
396
412
397 /// <summary>
413 /// <summary>
398 /// БцСпляСт нСсколько аснхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Указанная асинхронная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° послС
414 /// БцСпляСт нСсколько аснхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Указанная асинхронная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° послС
399 /// выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
415 /// выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
400 /// Π½ΠΎΠ²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
416 /// Π½ΠΎΠ²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
401 /// </summary>
417 /// </summary>
402 /// <typeparam name="TNew">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</typeparam>
418 /// <typeparam name="TNew">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</typeparam>
403 /// <param name="chained">Асинхронная опСрация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒΡΡ послС выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ.</param>
419 /// <param name="chained">Асинхронная опСрация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒΡΡ послС выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ.</param>
404 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
420 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
405 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΠ΅Ρ‰ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
421 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΠ΅Ρ‰ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
406 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ аснхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</returns>
422 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ аснхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</returns>
407 /// <param name = "cancel"></param>
423 /// <param name = "cancel"></param>
408 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error, Action cancel) {
424 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error, Action cancel) {
409
425
410 Safe.ArgumentNotNull(chained, "chained");
426 Safe.ArgumentNotNull(chained, "chained");
411
427
412 // ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ связывания Π΅Ρ‰Π΅ Π½Π΅ Π½Π°Ρ‡Π°Ρ‚Π° асинхронная опСрация, поэтому Π½ΡƒΠΆΠ½ΠΎ
428 // ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ связывания Π΅Ρ‰Π΅ Π½Π΅ Π½Π°Ρ‡Π°Ρ‚Π° асинхронная опСрация, поэтому Π½ΡƒΠΆΠ½ΠΎ
413 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π²Ρ‹Π·ΡΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
429 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π²Ρ‹Π·ΡΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
414 // ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ асинхронная опСрация, ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ посрСднику, Ρ‡Ρ‚ΠΎΠ±Ρ‹
430 // ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ асинхронная опСрация, ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ посрСднику, Ρ‡Ρ‚ΠΎΠ±Ρ‹
415 // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
431 // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
416 var medium = new Promise<TNew>(this);
432 var medium = new Promise<TNew>(this);
417
433
418 Action<T> resultHandler = delegate(T result) {
434 Action<T> resultHandler = delegate(T result) {
419 if (medium.IsCancelled)
435 if (medium.IsCancelled)
420 return;
436 return;
421
437
422 var promise = chained(result);
438 var promise = chained(result);
423
439
424 promise.Last(
440 promise.On(
425 medium.Resolve,
441 medium.Resolve,
426 medium.Reject,
442 medium.Reject,
427 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
443 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
428 );
444 );
429
445
430 // notify chained operation that it's not needed anymore
446 // notify chained operation that it's not needed anymore
431 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
447 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
432 // зависит IsExclusive
448 // зависит IsExclusive
433 medium.Last(
449 medium.On(
434 null,
450 null,
435 null,
451 null,
436 () => {
452 () => {
437 if (promise.IsExclusive)
453 if (promise.IsExclusive)
438 promise.Cancel();
454 promise.Cancel();
439 }
455 }
440 );
456 );
441 };
457 };
442
458
443 Func<Exception,T> errorHandler;
459 Func<Exception,T> errorHandler;
444
460
445 if (error != null)
461 if (error != null)
446 errorHandler = delegate(Exception e) {
462 errorHandler = delegate(Exception e) {
447 try {
463 try {
448 var promise = error(e);
464 var promise = error(e);
449
465
450 promise.Last(
466 promise.On(
451 medium.Resolve,
467 medium.Resolve,
452 medium.Reject,
468 medium.Reject,
453 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
469 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
454 );
470 );
455
471
456 // notify chained operation that it's not needed anymore
472 // notify chained operation that it's not needed anymore
457 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
473 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
458 // зависит IsExclusive
474 // зависит IsExclusive
459 medium.Cancelled(() => {
475 medium.Cancelled(() => {
460 if (promise.IsExclusive)
476 if (promise.IsExclusive)
461 promise.Cancel();
477 promise.Cancel();
462 });
478 });
463 } catch (Exception e2) {
479 } catch (Exception e2) {
464 medium.Reject(e2);
480 medium.Reject(e2);
465 }
481 }
466 return default(T);
482 return default(T);
467 };
483 };
468 else
484 else
469 errorHandler = err => {
485 errorHandler = err => {
470 medium.Reject(err);
486 medium.Reject(err);
471 return default(T);
487 return default(T);
472 };
488 };
473
489
474
490
475 Action cancelHandler;
491 Action cancelHandler;
476 if (cancel != null)
492 if (cancel != null)
477 cancelHandler = () => {
493 cancelHandler = () => {
478 if (cancel != null)
494 if (cancel != null)
479 cancel();
495 cancel();
480 medium.Cancel();
496 medium.Cancel();
481 };
497 };
482 else
498 else
483 cancelHandler = medium.Cancel;
499 cancelHandler = medium.Cancel;
484
500
485 AddHandler(
501 AddHandler(
486 resultHandler,
502 resultHandler,
487 errorHandler,
503 errorHandler,
488 cancelHandler,
504 cancelHandler,
489 null
505 null,
506 true
490 );
507 );
491
508
492 return medium;
509 return medium;
493 }
510 }
494
511
495 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error) {
512 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error) {
496 return Chain(chained, error, null);
513 return Chain(chained, error, null);
497 }
514 }
498
515
499 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained) {
516 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained) {
500 return Chain(chained, null, null);
517 return Chain(chained, null, null);
501 }
518 }
502
519
503 public IPromise<T> Cancelled(Action handler) {
520 public IPromise<T> Cancelled(Action handler) {
504 var medium = new Promise<T>(this);
521 var medium = new Promise<T>(this);
505 AddHandler(null, null, handler, medium);
522 AddHandler(null, null, handler, medium, false);
506 return medium;
523 return medium;
507 }
524 }
508
525
509 /// <summary>
526 /// <summary>
510 /// Adds the specified handler for all cases (success, error, cancel)
527 /// Adds the specified handler for all cases (success, error, cancel)
511 /// </summary>
528 /// </summary>
512 /// <param name="handler">The handler that will be called anyway</param>
529 /// <param name="handler">The handler that will be called anyway</param>
513 /// <returns>self</returns>
530 /// <returns>self</returns>
514 public IPromise<T> Anyway(Action handler) {
531 public IPromise<T> Anyway(Action handler) {
515 Safe.ArgumentNotNull(handler, "handler");
532 Safe.ArgumentNotNull(handler, "handler");
516
533
534 var medium = new Promise<T>(this);
535
517 AddHandler(
536 AddHandler(
518 x => handler(),
537 x => handler(),
519 e => {
538 e => {
520 handler();
539 handler();
521 throw new TransientPromiseException(e);
540 throw new TransientPromiseException(e);
522 },
541 },
523 handler,
542 handler,
524 null
543 medium,
544 true
525 );
545 );
526 return this;
546
547 return medium;
527 }
548 }
528
549
529 /// <summary>
550 /// <summary>
530 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ
551 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ
531 /// </summary>
552 /// </summary>
532 /// <typeparam name="T2"></typeparam>
553 /// <typeparam name="T2"></typeparam>
533 /// <returns></returns>
554 /// <returns></returns>
534 public IPromise<T2> Cast<T2>() {
555 public IPromise<T2> Cast<T2>() {
535 return Then(x => (T2)(object)x, null);
556 return Then(x => (T2)(object)x, null);
536 }
557 }
537
558
538 /// <summary>
559 /// <summary>
539 /// ДоТидаСтся ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ обСщания ΠΈ Π² случаС успСха, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
560 /// ДоТидаСтся ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ обСщания ΠΈ Π² случаС успСха, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
540 /// Π΅Π³ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС бросаСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
561 /// Π΅Π³ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС бросаСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
541 /// </summary>
562 /// </summary>
542 /// <remarks>
563 /// <remarks>
543 /// <para>
564 /// <para>
544 /// Если ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ обСщания Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ, это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚,
565 /// Если ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ обСщания Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ, это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚,
545 /// Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² этом Ρ€ΠΎΠ΄Π΅, это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
566 /// Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² этом Ρ€ΠΎΠ΄Π΅, это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
546 /// ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΅Π³ΠΎ Π½Π΅ доТдались, ΠΎΠ΄Π½Π°ΠΊΠΎ всС зарСгистрированныС
567 /// ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΅Π³ΠΎ Π½Π΅ доТдались, ΠΎΠ΄Π½Π°ΠΊΠΎ всС зарСгистрированныС
547 /// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΈ Ρ‚Π°ΠΊ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΈ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹, ΠΊΠΎΠ³Π΄Π°
568 /// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΈ Ρ‚Π°ΠΊ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΈ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹, ΠΊΠΎΠ³Π΄Π°
548 /// ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
569 /// ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
549 /// </para>
570 /// </para>
550 /// <para>
571 /// <para>
551 /// Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΡ‚Π΅Ρ‡ΡŒ
572 /// Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΡ‚Π΅Ρ‡ΡŒ
552 /// Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΈ
573 /// Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΈ
553 /// ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ
574 /// ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ
554 /// ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ.
575 /// ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ.
555 /// </para>
576 /// </para>
556 /// </remarks>
577 /// </remarks>
557 /// <param name="timeout">ВрСмя оТидания</param>
578 /// <param name="timeout">ВрСмя оТидания</param>
558 /// <returns>Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния обСщания</returns>
579 /// <returns>Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния обСщания</returns>
559 public T Join(int timeout) {
580 public T Join(int timeout) {
560 var evt = new ManualResetEvent(false);
581 var evt = new ManualResetEvent(false);
561 Anyway(() => evt.Set());
582 Anyway(() => evt.Set());
562
583
563 if (!evt.WaitOne(timeout, true))
584 if (!evt.WaitOne(timeout, true))
564 throw new TimeoutException();
585 throw new TimeoutException();
565
586
566 switch (m_state) {
587 switch (m_state) {
567 case SUCCEEDED_STATE:
588 case SUCCEEDED_STATE:
568 return m_result;
589 return m_result;
569 case CANCELLED_STATE:
590 case CANCELLED_STATE:
570 throw new OperationCanceledException();
591 throw new OperationCanceledException();
571 case REJECTED_STATE:
592 case REJECTED_STATE:
572 throw new TargetInvocationException(m_error);
593 throw new TargetInvocationException(m_error);
573 default:
594 default:
574 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
595 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
575 }
596 }
576 }
597 }
577
598
578 public T Join() {
599 public T Join() {
579 return Join(Timeout.Infinite);
600 return Join(Timeout.Infinite);
580 }
601 }
581
602
582 void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium) {
603 void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium, bool inc) {
583 if (success != null || error != null)
604 if (inc)
584 Interlocked.Increment(ref m_childrenCount);
605 Interlocked.Increment(ref m_childrenCount);
585
606
586 var handler = new HandlerDescriptor {
607 var handler = new HandlerDescriptor {
587 resultHandler = success,
608 resultHandler = success,
588 errorHandler = error,
609 errorHandler = error,
589 cancellHandler = cancel,
610 cancellHandler = cancel,
590 medium = medium
611 medium = medium
591 };
612 };
592
613
593 bool queued;
614 bool queued;
594
615
595 if (!IsResolved) {
616 if (!IsResolved) {
596 m_handlers.Enqueue(handler);
617 m_handlers.Enqueue(handler);
597 queued = true;
618 queued = true;
598 } else {
619 } else {
599 // the promise is in resolved state, just invoke the handled with minimum overhead
620 // the promise is in resolved state, just invoke the handled with minimum overhead
600 queued = false;
621 queued = false;
601 InvokeHandler(handler);
622 InvokeHandler(handler);
602 }
623 }
603
624
604 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
625 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
605 // if the promise have been resolved while we was adding handler to the queue
626 // if the promise have been resolved while we was adding handler to the queue
606 // we can't guarantee that someone is still processing it
627 // we can't guarantee that someone is still processing it
607 // therefore we will fetch a handler from the queue and execute it
628 // therefore we will fetch a handler from the queue and execute it
608 // note that fetched handler may be not the one that we have added
629 // note that fetched handler may be not the one that we have added
609 // even we can fetch no handlers at all :)
630 // even we can fetch no handlers at all :)
610 InvokeHandler(handler);
631 InvokeHandler(handler);
611 }
632 }
612
633
613 protected virtual void InvokeHandler(HandlerDescriptor handler) {
634 protected virtual void InvokeHandler(HandlerDescriptor handler) {
614 switch (m_state) {
635 switch (m_state) {
615 case SUCCEEDED_STATE:
636 case SUCCEEDED_STATE:
616 handler.Resolve(m_result);
637 handler.Resolve(m_result);
617 break;
638 break;
618 case REJECTED_STATE:
639 case REJECTED_STATE:
619 handler.Reject(m_error);
640 handler.Reject(m_error);
620 break;
641 break;
621 case CANCELLED_STATE:
642 case CANCELLED_STATE:
622 handler.Cancel();
643 handler.Cancel();
623 break;
644 break;
624 default:
645 default:
625 // do nothing
646 // do nothing
626 return;
647 return;
627 }
648 }
628 }
649 }
629
650
630 void OnStateChanged() {
651 void OnStateChanged() {
631 HandlerDescriptor handler;
652 HandlerDescriptor handler;
632 while (m_handlers.TryDequeue(out handler))
653 while (m_handlers.TryDequeue(out handler))
633 InvokeHandler(handler);
654 InvokeHandler(handler);
634 }
655 }
635
656
636 public bool IsExclusive {
657 public bool IsExclusive {
637 get {
658 get {
638 return m_childrenCount <= 1;
659 return m_childrenCount <= 1;
639 }
660 }
640 }
661 }
641
662
642 /// <summary>
663 /// <summary>
643 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
664 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
644 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
665 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
645 /// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ обСщания, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ обСщания Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹, Ссли Π½ΠΈΠΊΡ‚ΠΎ большС Π½Π° Π½ΠΈΡ… Π½Π΅ подписан.
666 /// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ обСщания, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ обСщания Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹, Ссли Π½ΠΈΠΊΡ‚ΠΎ большС Π½Π° Π½ΠΈΡ… Π½Π΅ подписан.
646 /// </summary>
667 /// </summary>
647 /// <param name="promises">Бписок ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. Если список пустой, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ возвращаСтся ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΌ.</param>
668 /// <param name="promises">Бписок ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. Если список пустой, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ возвращаСтся ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΌ.</param>
648 /// <returns>ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.</returns>
669 /// <returns>ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.</returns>
649 /// <exception cref="ArgumentNullException"><paramref name="promises"/> Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ null</exception>
670 /// <exception cref="ArgumentNullException"><paramref name="promises"/> Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ null</exception>
650 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
671 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
651 if (promises == null)
672 if (promises == null)
652 throw new ArgumentNullException();
673 throw new ArgumentNullException();
653
674
654 // создаСм аккумулятор для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
675 // создаСм аккумулятор для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
655 var result = new T[promises.Count];
676 var result = new T[promises.Count];
656 var promise = new Promise<T[]>();
677 var promise = new Promise<T[]>();
657
678
658 // special case
679 // special case
659 if (promises.Count == 0) {
680 if (promises.Count == 0) {
660 promise.Resolve(result);
681 promise.Resolve(result);
661 return promise;
682 return promise;
662 }
683 }
663
684
664 int pending = promises.Count;
685 int pending = promises.Count;
665
686
666 for (int i = 0; i < promises.Count; i++) {
687 for (int i = 0; i < promises.Count; i++) {
667 var dest = i;
688 var dest = i;
668
689
669 if (promises[i] != null) {
690 if (promises[i] != null) {
670 promises[i].Then(
691 promises[i].Then(
671 x => {
692 x => {
672 result[dest] = x;
693 result[dest] = x;
673 if (Interlocked.Decrement(ref pending) == 0)
694 if (Interlocked.Decrement(ref pending) == 0)
674 promise.Resolve(result);
695 promise.Resolve(result);
675 },
696 },
676 e => {
697 e => {
677 promise.Reject(e);
698 promise.Reject(e);
678 return default(T);
699 return default(T);
679 }
700 }
680 );
701 );
681 } else {
702 } else {
682 if (Interlocked.Decrement(ref pending) == 0)
703 if (Interlocked.Decrement(ref pending) == 0)
683 promise.Resolve(result);
704 promise.Resolve(result);
684 }
705 }
685 }
706 }
686
707
687 promise.Cancelled(
708 promise.Cancelled(
688 () => {
709 () => {
689 foreach (var d in promises)
710 foreach (var d in promises)
690 if (d != null && d.IsExclusive)
711 if (d != null && d.IsExclusive)
691 d.Cancel();
712 d.Cancel();
692 }
713 }
693 );
714 );
694
715
695 return promise;
716 return promise;
696 }
717 }
697
718
698 /// <summary>
719 /// <summary>
699 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
720 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
700 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
721 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
701 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
722 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
702 /// </summary>
723 /// </summary>
703 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
724 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
704 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
725 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
705 /// <remarks>
726 /// <remarks>
706 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
727 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
707 /// </remarks>
728 /// </remarks>
708 public static IPromise CreateComposite(ICollection<IPromise> promises) {
729 public static IPromise CreateComposite(ICollection<IPromise> promises) {
709 if (promises == null)
730 if (promises == null)
710 throw new ArgumentNullException();
731 throw new ArgumentNullException();
711 if (promises.Count == 0)
732 if (promises.Count == 0)
712 return Promise<object>.ResultToPromise(null);
733 return Promise<object>.ResultToPromise(null);
713
734
714 int countdown = promises.Count;
735 int countdown = promises.Count;
715
736
716 var result = new Promise<object>();
737 var result = new Promise<object>();
717
738
718 foreach (var d in promises) {
739 foreach (var d in promises) {
719 if (d == null) {
740 if (d == null) {
720 if (Interlocked.Decrement(ref countdown) == 0)
741 if (Interlocked.Decrement(ref countdown) == 0)
721 result.Resolve(null);
742 result.Resolve(null);
722 } else {
743 } else {
723 d.Then(() => {
744 d.Then(() => {
724 if (Interlocked.Decrement(ref countdown) == 0)
745 if (Interlocked.Decrement(ref countdown) == 0)
725 result.Resolve(null);
746 result.Resolve(null);
726 });
747 });
727 }
748 }
728 }
749 }
729
750
730 result.Cancelled(() => {
751 result.Cancelled(() => {
731 foreach (var d in promises)
752 foreach (var d in promises)
732 if (d != null && d.IsExclusive)
753 if (d != null && d.IsExclusive)
733 d.Cancel();
754 d.Cancel();
734 });
755 });
735
756
736 return result;
757 return result;
737 }
758 }
738
759
739 public static Promise<T> ResultToPromise(T result) {
760 public static Promise<T> ResultToPromise(T result) {
740 var p = new Promise<T>();
761 var p = new Promise<T>();
741 p.Resolve(result);
762 p.Resolve(result);
742 return p;
763 return p;
743 }
764 }
744
765
745 public static Promise<T> ExceptionToPromise(Exception error) {
766 public static Promise<T> ExceptionToPromise(Exception error) {
746 if (error == null)
767 if (error == null)
747 throw new ArgumentNullException();
768 throw new ArgumentNullException();
748
769
749 var p = new Promise<T>();
770 var p = new Promise<T>();
750 p.Reject(error);
771 p.Reject(error);
751 return p;
772 return p;
752 }
773 }
753
774
754 #region IPromiseBase explicit implementation
775 #region IPromiseBase explicit implementation
755
776
756 IPromise IPromise.Then(Action success, Action<Exception> error, Action cancel) {
777 IPromise IPromise.Then(Action success, Action<Exception> error, Action cancel) {
757 return Then(
778 return Then(
758 success != null ? new Action<T>(x => success()) : null,
779 success != null ? new Action<T>(x => success()) : null,
759 error != null ? new Func<Exception,T>(e => {
780 error != null ? new Func<Exception,T>(e => {
760 error(e);
781 error(e);
761 return default(T);
782 return default(T);
762 }) : null,
783 }) : null,
763 cancel
784 cancel
764 );
785 );
765 }
786 }
766
787
767 IPromise IPromise.Then(Action success, Action<Exception> error) {
788 IPromise IPromise.Then(Action success, Action<Exception> error) {
768 return Then(
789 return Then(
769 success != null ? new Action<T>(x => success()) : null,
790 success != null ? new Action<T>(x => success()) : null,
770 error != null ? new Func<Exception,T>(e => {
791 error != null ? new Func<Exception,T>(e => {
771 error(e);
792 error(e);
772 return default(T);
793 return default(T);
773 }) : null
794 }) : null
774 );
795 );
775 }
796 }
776
797
777 IPromise IPromise.Then(Action success) {
798 IPromise IPromise.Then(Action success) {
778 Safe.ArgumentNotNull(success, "success");
799 Safe.ArgumentNotNull(success, "success");
779 return Then(x => success());
800 return Then(x => success());
780 }
801 }
781
802
782 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
803 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
783 return ChainNoResult(chained, error, cancel);
804 return ChainNoResult(chained, error, cancel);
784 }
805 }
785
806
786 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
807 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
787 Safe.ArgumentNotNull(chained, "chained");
808 Safe.ArgumentNotNull(chained, "chained");
788
809
789 var medium = new Promise<object>(this);
810 var medium = new Promise<object>(this);
790
811
791 Action<T> resultHandler = delegate {
812 Action<T> resultHandler = delegate {
792 if (medium.IsCancelled)
813 if (medium.IsCancelled)
793 return;
814 return;
794
815
795 var promise = chained();
816 var promise = chained();
796
817
797 promise.Last(
818 promise.On(
798 medium.Resolve,
819 medium.Resolve,
799 medium.Reject,
820 medium.Reject,
800 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
821 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
801 );
822 );
802
823
803 // notify chained operation that it's not needed anymore
824 // notify chained operation that it's not needed anymore
804 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
825 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
805 // зависит IsExclusive
826 // зависит IsExclusive
806 medium.Cancelled(() => {
827 medium.Cancelled(() => {
807 if (promise.IsExclusive)
828 if (promise.IsExclusive)
808 promise.Cancel();
829 promise.Cancel();
809 });
830 });
810 };
831 };
811
832
812 Func<Exception,T> errorHandler;
833 Func<Exception,T> errorHandler;
813
834
814 if (error != null)
835 if (error != null)
815 errorHandler = delegate(Exception e) {
836 errorHandler = delegate(Exception e) {
816 try {
837 try {
817 var promise = error(e);
838 var promise = error(e);
818
839
819 promise.Last(
840 promise.On(
820 medium.Resolve,
841 medium.Resolve,
821 medium.Reject,
842 medium.Reject,
822 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
843 () => medium.Reject(new OperationCanceledException()) // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
823 );
844 );
824
845
825 // notify chained operation that it's not needed anymore
846 // notify chained operation that it's not needed anymore
826 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
847 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
827 // зависит IsExclusive
848 // зависит IsExclusive
828 medium.Cancelled(() => {
849 medium.Cancelled(() => {
829 if (promise.IsExclusive)
850 if (promise.IsExclusive)
830 promise.Cancel();
851 promise.Cancel();
831 });
852 });
832 } catch (Exception e2) {
853 } catch (Exception e2) {
833 medium.Reject(e2);
854 medium.Reject(e2);
834 }
855 }
835 return default(T);
856 return default(T);
836 };
857 };
837 else
858 else
838 errorHandler = err => {
859 errorHandler = err => {
839 medium.Reject(err);
860 medium.Reject(err);
840 return default(T);
861 return default(T);
841 };
862 };
842
863
843
864
844 Action cancelHandler;
865 Action cancelHandler;
845 if (cancel != null)
866 if (cancel != null)
846 cancelHandler = () => {
867 cancelHandler = () => {
847 if (cancel != null)
868 if (cancel != null)
848 cancel();
869 cancel();
849 medium.Cancel();
870 medium.Cancel();
850 };
871 };
851 else
872 else
852 cancelHandler = medium.Cancel;
873 cancelHandler = medium.Cancel;
853
874
854 AddHandler(
875 AddHandler(
855 resultHandler,
876 resultHandler,
856 errorHandler,
877 errorHandler,
857 cancelHandler,
878 cancelHandler,
858 null
879 null,
859 );
880 true
881 );
860
882
861 return medium;
883 return medium;
862 }
884 }
885
863 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) {
886 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) {
864 return ChainNoResult(chained, error, null);
887 return ChainNoResult(chained, error, null);
865 }
888 }
889
866 IPromise IPromise.Chain(Func<IPromise> chained) {
890 IPromise IPromise.Chain(Func<IPromise> chained) {
867 return ChainNoResult(chained, null, null);
891 return ChainNoResult(chained, null, null);
868 }
892 }
869
893
870
894
871 void IPromise.Last(Action success, Action<Exception> error, Action cancel) {
895 void IPromise.On(Action success, Action<Exception> error, Action cancel) {
872 Last(x => success(), error, cancel);
896 On(x => success(), error, cancel);
873 }
897 }
874
898
875 void IPromise.Last(Action success, Action<Exception> error) {
899 void IPromise.On(Action success, Action<Exception> error) {
876 Last(x => success(), error, null);
900 On(x => success(), error, null);
877 }
901 }
878
902
879 void IPromise.Last(Action success) {
903 void IPromise.On(Action success) {
880 Last(x => success(), null, null);
904 On(x => success(), null, null);
881 }
905 }
882
906
883 IPromise IPromise.Error(Action<Exception> error) {
907 IPromise IPromise.Error(Action<Exception> error) {
884 return Error(error);
908 return Error(error);
885 }
909 }
886
910
887 IPromise IPromise.Anyway(Action handler) {
911 IPromise IPromise.Anyway(Action handler) {
888 return Anyway(handler);
912 return Anyway(handler);
889 }
913 }
890
914
891 IPromise IPromise.Cancelled(Action handler) {
915 IPromise IPromise.Cancelled(Action handler) {
892 return Cancelled(handler);
916 return Cancelled(handler);
893 }
917 }
894
918
895 void IPromise.Join() {
919 void IPromise.Join() {
896 Join();
920 Join();
897 }
921 }
898
922
899 void IPromise.Join(int timeout) {
923 void IPromise.Join(int timeout) {
900 Join(timeout);
924 Join(timeout);
901 }
925 }
902
926
903 #endregion
927 #endregion
904
928
905
929
906
930
907 }
931 }
908 }
932 }
@@ -1,83 +1,83
1 using System.Threading;
1 using System.Threading;
2 using System;
2 using System;
3 #if NET_4_5
3 #if NET_4_5
4 using System.Threading.Tasks;
4 using System.Threading.Tasks;
5 #endif
5 #endif
6
6
7 namespace Implab {
7 namespace Implab {
8 public static class PromiseExtensions {
8 public static class PromiseExtensions {
9 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
9 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
10 Safe.ArgumentNotNull(that, "that");
10 Safe.ArgumentNotNull(that, "that");
11 var context = SynchronizationContext.Current;
11 var context = SynchronizationContext.Current;
12 if (context == null)
12 if (context == null)
13 return that;
13 return that;
14
14
15 var p = new SyncContextPromise<T>(context, that);
15 var p = new SyncContextPromise<T>(context, that);
16
16
17 that.Last(
17 that.On(
18 p.Resolve,
18 p.Resolve,
19 p.Reject,
19 p.Reject,
20 p.Cancel
20 p.Cancel
21 );
21 );
22 return p;
22 return p;
23 }
23 }
24
24
25 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
25 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
26 Safe.ArgumentNotNull(that, "that");
26 Safe.ArgumentNotNull(that, "that");
27 Safe.ArgumentNotNull(context, "context");
27 Safe.ArgumentNotNull(context, "context");
28
28
29 var p = new SyncContextPromise<T>(context, that);
29 var p = new SyncContextPromise<T>(context, that);
30
30
31 that.Last(
31 that.On(
32 p.Resolve,
32 p.Resolve,
33 p.Reject,
33 p.Reject,
34 p.Cancel
34 p.Cancel
35 );
35 );
36 return p;
36 return p;
37 }
37 }
38
38
39 /// <summary>
39 /// <summary>
40 /// Ensures the dispatched.
40 /// Ensures the dispatched.
41 /// </summary>
41 /// </summary>
42 /// <returns>The dispatched.</returns>
42 /// <returns>The dispatched.</returns>
43 /// <param name="that">That.</param>
43 /// <param name="that">That.</param>
44 /// <param name="head">Head.</param>
44 /// <param name="head">Head.</param>
45 /// <param name="cleanup">Cleanup.</param>
45 /// <param name="cleanup">Cleanup.</param>
46 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
46 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
47 /// <typeparam name="T">The 2nd type parameter.</typeparam>
47 /// <typeparam name="T">The 2nd type parameter.</typeparam>
48 public static TPromise EnsureDispatched<TPromise,T>(this TPromise that, IPromise<T> head, Action<T> cleanup) where TPromise : IPromise{
48 public static TPromise EnsureDispatched<TPromise,T>(this TPromise that, IPromise<T> head, Action<T> cleanup) where TPromise : IPromise{
49 Safe.ArgumentNotNull(that, "that");
49 Safe.ArgumentNotNull(that, "that");
50 Safe.ArgumentNotNull(head, "head");
50 Safe.ArgumentNotNull(head, "head");
51
51
52 that.Last(null,null,() => head.Last(cleanup));
52 that.On(null,null,() => head.On(cleanup));
53
53
54 return that;
54 return that;
55 }
55 }
56
56
57 public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult,T> callback) {
57 public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult,T> callback) {
58 Safe.ArgumentNotNull(that, "that");
58 Safe.ArgumentNotNull(that, "that");
59 Safe.ArgumentNotNull(callback, "callback");
59 Safe.ArgumentNotNull(callback, "callback");
60 return ar => {
60 return ar => {
61 try {
61 try {
62 that.Resolve(callback(ar));
62 that.Resolve(callback(ar));
63 } catch (Exception err) {
63 } catch (Exception err) {
64 that.Reject(err);
64 that.Reject(err);
65 }
65 }
66 };
66 };
67 }
67 }
68
68
69 #if NET_4_5
69 #if NET_4_5
70
70
71 public static Task<T> GetTask<T>(this IPromise<T> that) {
71 public static Task<T> GetTask<T>(this IPromise<T> that) {
72 Safe.ArgumentNotNull(that, "that");
72 Safe.ArgumentNotNull(that, "that");
73 var tcs = new TaskCompletionSource<T>();
73 var tcs = new TaskCompletionSource<T>();
74
74
75 that.Last(tcs.SetResult, tcs.SetException, tcs.SetCanceled);
75 that.On(tcs.SetResult, tcs.SetException, tcs.SetCanceled);
76
76
77 return tcs.Task;
77 return tcs.Task;
78 }
78 }
79
79
80 #endif
80 #endif
81 }
81 }
82 }
82 }
83
83
@@ -1,48 +1,48
1 using System;
1 using System;
2 using Implab.Diagnostics;
2 using Implab.Diagnostics;
3 using Implab.Parallels;
3 using Implab.Parallels;
4 using Implab;
4 using Implab;
5 using System.Collections.Generic;
5 using System.Collections.Generic;
6 using System.Collections.Concurrent;
6 using System.Collections.Concurrent;
7
7
8 namespace MonoPlay {
8 namespace MonoPlay {
9 class MainClass {
9 class MainClass {
10 public static void Main(string[] args) {
10 public static void Main(string[] args) {
11 if (args == null)
11 if (args == null)
12 throw new ArgumentNullException("args");
12 throw new ArgumentNullException("args");
13
13
14 var q1 = new MTQueue<int>();
14 var q1 = new MTQueue<int>();
15 var q2 = new ConcurrentQueue<int>();
15 var q2 = new Queue<int>();
16
16
17 const int count = 10000000;
17 const int count = 10000000;
18
18
19 var t1 = Environment.TickCount;
19 var t1 = Environment.TickCount;
20
20
21 for (var i = 0; i < count; i++)
21 for (var i = 0; i < count; i++)
22 q1.Enqueue(i);
22 q1.Enqueue(i);
23
23
24 var t2 = Environment.TickCount;
24 var t2 = Environment.TickCount;
25 Console.WriteLine("MTQueue: {0} ms", t2 - t1);
25 Console.WriteLine("MTQueue: {0} ms", t2 - t1);
26
26
27 t1 = Environment.TickCount;
27 t1 = Environment.TickCount;
28
28
29 for (var i = 0; i < count; i++)
29 for (var i = 0; i < count; i++)
30 q2.Enqueue(i);
30 q2.Enqueue(i);
31
31
32 t2 = Environment.TickCount;
32 t2 = Environment.TickCount;
33 Console.WriteLine("LinkedList: {0} ms", t2 - t1);
33 Console.WriteLine("LinkedList: {0} ms", t2 - t1);
34
34
35 q2 = new ConcurrentQueue<int>();
35 q2 = new Queue<int>();
36
36
37 t1 = Environment.TickCount;
37 t1 = Environment.TickCount;
38
38
39 for (var i = 0; i < count; i++)
39 for (var i = 0; i < count; i++)
40 lock (q2)
40 lock (q2)
41 q2.Enqueue(i);
41 q2.Enqueue(i);
42
42
43 t2 = Environment.TickCount;
43 t2 = Environment.TickCount;
44 Console.WriteLine("LinkedList+Lock: {0} ms", t2 - t1);
44 Console.WriteLine("LinkedList+Lock: {0} ms", t2 - t1);
45
45
46 }
46 }
47 }
47 }
48 }
48 }
General Comments 0
You need to be logged in to leave comments. Login now