##// END OF EJS Templates
Слияние с default
cin -
r199:43b1017ce100 merge v2
parent child
Show More
@@ -0,0 +1,1
1 f1da3afc3521e0e1631ac19e09690bc0a241841a release v2.1
@@ -1,142 +1,140
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3
3
4 namespace Implab {
4 namespace Implab {
5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
6 public struct HandlerDescriptor {
6 public struct HandlerDescriptor {
7 readonly Action m_handler;
7 readonly Action m_handler;
8 readonly Action<Exception> m_error;
8 readonly Action<Exception> m_error;
9 readonly Action<Exception> m_cancel;
9 readonly Action<Exception> m_cancel;
10 readonly PromiseEventType m_mask;
10 readonly PromiseEventType m_mask;
11
11
12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
13 m_handler = success;
13 m_handler = success;
14 m_error = error;
14 m_error = error;
15 m_cancel = cancel;
15 m_cancel = cancel;
16 m_mask = PromiseEventType.Success;
16 m_mask = PromiseEventType.Success;
17 }
17 }
18
18
19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
20 m_handler = handler;
20 m_handler = handler;
21 m_error = null;
21 m_error = null;
22 m_cancel = null;
22 m_cancel = null;
23 m_mask = mask;
23 m_mask = mask;
24 }
24 }
25
25
26 public void SignalSuccess() {
26 public void SignalSuccess() {
27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
28 try {
28 try {
29 m_handler();
29 m_handler();
30 } catch (Exception err) {
30 // Analysis disable once EmptyGeneralCatchClause
31 // avoid calling handler twice in case of error
31 } catch {
32 if (m_error != null)
33 SignalError(err);
34 }
32 }
35 }
33 }
36 }
34 }
37
35
38 public void SignalError(Exception err) {
36 public void SignalError(Exception err) {
39 if (m_error != null) {
37 if (m_error != null) {
40 try {
38 try {
41 m_error(err);
39 m_error(err);
42 // Analysis disable once EmptyGeneralCatchClause
40 // Analysis disable once EmptyGeneralCatchClause
43 } catch {
41 } catch {
44 }
42 }
45 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
43 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
46 try {
44 try {
47 m_handler();
45 m_handler();
48 // Analysis disable once EmptyGeneralCatchClause
46 // Analysis disable once EmptyGeneralCatchClause
49 } catch {
47 } catch {
50 }
48 }
51 }
49 }
52 }
50 }
53
51
54 public void SignalCancel(Exception reason) {
52 public void SignalCancel(Exception reason) {
55 if (m_cancel != null) {
53 if (m_cancel != null) {
56 try {
54 try {
57 m_cancel(reason);
55 m_cancel(reason);
58 } catch (Exception err) {
56 // Analysis disable once EmptyGeneralCatchClause
59 SignalError(err);
57 } catch {
60 }
58 }
61 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
59 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
62 try {
60 try {
63 m_handler();
61 m_handler();
64 // Analysis disable once EmptyGeneralCatchClause
62 // Analysis disable once EmptyGeneralCatchClause
65 } catch {
63 } catch {
66 }
64 }
67 }
65 }
68 }
66 }
69 }
67 }
70
68
71
69
72 #region implemented abstract members of AbstractPromise
70 #region implemented abstract members of AbstractPromise
73
71
74 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
72 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
75 switch (signal) {
73 switch (signal) {
76 case SUCCEEDED_STATE:
74 case SUCCEEDED_STATE:
77 handler.SignalSuccess();
75 handler.SignalSuccess();
78 break;
76 break;
79 case REJECTED_STATE:
77 case REJECTED_STATE:
80 handler.SignalError(Error);
78 handler.SignalError(Error);
81 break;
79 break;
82 case CANCELLED_STATE:
80 case CANCELLED_STATE:
83 handler.SignalCancel(CancellationReason);
81 handler.SignalCancel(CancellationReason);
84 break;
82 break;
85 default:
83 default:
86 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
84 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
87 }
85 }
88 }
86 }
89
87
90 protected override Signal GetResolveSignal() {
88 protected override Signal GetResolveSignal() {
91 var signal = new Signal();
89 var signal = new Signal();
92 On(signal.Set, PromiseEventType.All);
90 On(signal.Set, PromiseEventType.All);
93 return signal;
91 return signal;
94 }
92 }
95
93
96 #endregion
94 #endregion
97
95
98 public Type PromiseType {
96 public Type PromiseType {
99 get {
97 get {
100 return typeof(void);
98 return typeof(void);
101 }
99 }
102 }
100 }
103
101
104 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
102 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
105 AddHandler(new HandlerDescriptor(success, error, cancel));
103 AddHandler(new HandlerDescriptor(success, error, cancel));
106 return this;
104 return this;
107 }
105 }
108
106
109 public IPromise On(Action success, Action<Exception> error) {
107 public IPromise On(Action success, Action<Exception> error) {
110 AddHandler(new HandlerDescriptor(success, error, null));
108 AddHandler(new HandlerDescriptor(success, error, null));
111 return this;
109 return this;
112 }
110 }
113
111
114 public IPromise On(Action success) {
112 public IPromise On(Action success) {
115 AddHandler(new HandlerDescriptor(success, null, null));
113 AddHandler(new HandlerDescriptor(success, null, null));
116 return this;
114 return this;
117 }
115 }
118
116
119 public IPromise On(Action handler, PromiseEventType events) {
117 public IPromise On(Action handler, PromiseEventType events) {
120 AddHandler(new HandlerDescriptor(handler,events));
118 AddHandler(new HandlerDescriptor(handler,events));
121 return this;
119 return this;
122 }
120 }
123
121
124 public IPromise<T> Cast<T>() {
122 public IPromise<T> Cast<T>() {
125 throw new InvalidCastException();
123 throw new InvalidCastException();
126 }
124 }
127
125
128 public void Join() {
126 public void Join() {
129 WaitResult(-1);
127 WaitResult(-1);
130 }
128 }
131
129
132 public void Join(int timeout) {
130 public void Join(int timeout) {
133 WaitResult(timeout);
131 WaitResult(timeout);
134 }
132 }
135
133
136 protected void SetResult() {
134 protected void SetResult() {
137 if(BeginSetResult())
135 if(BeginSetResult())
138 EndSetResult();
136 EndSetResult();
139 }
137 }
140 }
138 }
141 }
139 }
142
140
@@ -1,206 +1,204
1 using System;
1 using System;
2 using Implab.Parallels;
2 using Implab.Parallels;
3
3
4 namespace Implab {
4 namespace Implab {
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
6 public struct HandlerDescriptor {
6 public struct HandlerDescriptor {
7 readonly Action m_handler;
7 readonly Action m_handler;
8 readonly Action<T> m_success;
8 readonly Action<T> m_success;
9 readonly Action<Exception> m_error;
9 readonly Action<Exception> m_error;
10 readonly Action<Exception> m_cancel;
10 readonly Action<Exception> m_cancel;
11 readonly PromiseEventType m_mask;
11 readonly PromiseEventType m_mask;
12
12
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
14 m_success = success;
14 m_success = success;
15 m_error = error;
15 m_error = error;
16 m_cancel = cancel;
16 m_cancel = cancel;
17
17
18 m_handler = null;
18 m_handler = null;
19 m_mask = 0;
19 m_mask = 0;
20 }
20 }
21
21
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
23 m_handler = success;
23 m_handler = success;
24 m_success = null;
24 m_success = null;
25 m_error = error;
25 m_error = error;
26 m_cancel = cancel;
26 m_cancel = cancel;
27 m_mask = PromiseEventType.Success;
27 m_mask = PromiseEventType.Success;
28 }
28 }
29
29
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
31 m_handler = handler;
31 m_handler = handler;
32 m_mask = mask;
32 m_mask = mask;
33 m_success = null;
33 m_success = null;
34 m_error = null;
34 m_error = null;
35 m_cancel = null;
35 m_cancel = null;
36 }
36 }
37
37
38 public void SignalSuccess(T result) {
38 public void SignalSuccess(T result) {
39 if (m_success != null) {
39 if (m_success != null) {
40 try {
40 try {
41 m_success(result);
41 m_success(result);
42 } catch(Exception err) {
42 // Analysis disable once EmptyGeneralCatchClause
43 SignalError(err);
43 } catch {
44 }
44 }
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
46 try {
46 try {
47 m_handler();
47 m_handler();
48 } catch(Exception err) {
48 // Analysis disable once EmptyGeneralCatchClause
49 // avoid calling handler twice in case of error
49 } catch {
50 if (m_error != null)
51 SignalError(err);
52 }
50 }
53 }
51 }
54 }
52 }
55
53
56 public void SignalError(Exception err) {
54 public void SignalError(Exception err) {
57 if (m_error != null) {
55 if (m_error != null) {
58 try {
56 try {
59 m_error(err);
57 m_error(err);
60 // Analysis disable once EmptyGeneralCatchClause
58 // Analysis disable once EmptyGeneralCatchClause
61 } catch {
59 } catch {
62 }
60 }
63 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
61 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
64 try {
62 try {
65 m_handler();
63 m_handler();
66 // Analysis disable once EmptyGeneralCatchClause
64 // Analysis disable once EmptyGeneralCatchClause
67 } catch {
65 } catch {
68 }
66 }
69 }
67 }
70 }
68 }
71
69
72 public void SignalCancel(Exception reason) {
70 public void SignalCancel(Exception reason) {
73 if (m_cancel != null) {
71 if (m_cancel != null) {
74 try {
72 try {
75 m_cancel(reason);
73 m_cancel(reason);
76 } catch (Exception err) {
74 // Analysis disable once EmptyGeneralCatchClause
77 SignalError(err);
75 } catch {
78 }
76 }
79 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
77 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
80 try {
78 try {
81 m_handler();
79 m_handler();
82 // Analysis disable once EmptyGeneralCatchClause
80 // Analysis disable once EmptyGeneralCatchClause
83 } catch {
81 } catch {
84 }
82 }
85 }
83 }
86 }
84 }
87 }
85 }
88
86
89 public Type PromiseType {
87 public Type PromiseType {
90 get {
88 get {
91 return typeof(T);
89 return typeof(T);
92 }
90 }
93 }
91 }
94
92
95 public T Join() {
93 public T Join() {
96 WaitResult(-1);
94 WaitResult(-1);
97 return m_result;
95 return m_result;
98 }
96 }
99 public T Join(int timeout) {
97 public T Join(int timeout) {
100 WaitResult(timeout);
98 WaitResult(timeout);
101 return m_result;
99 return m_result;
102 }
100 }
103
101
104 void IPromise.Join() {
102 void IPromise.Join() {
105 WaitResult(-1);
103 WaitResult(-1);
106 }
104 }
107 void IPromise.Join(int timeout) {
105 void IPromise.Join(int timeout) {
108 WaitResult(timeout);
106 WaitResult(timeout);
109 }
107 }
110
108
111 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
109 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
112 AddHandler(new HandlerDescriptor(success, error, cancel));
110 AddHandler(new HandlerDescriptor(success, error, cancel));
113 return this;
111 return this;
114 }
112 }
115
113
116 public IPromise<T> On(Action<T> success, Action<Exception> error) {
114 public IPromise<T> On(Action<T> success, Action<Exception> error) {
117 AddHandler(new HandlerDescriptor(success, error, null));
115 AddHandler(new HandlerDescriptor(success, error, null));
118 return this;
116 return this;
119 }
117 }
120
118
121 public IPromise<T> On(Action<T> success) {
119 public IPromise<T> On(Action<T> success) {
122 AddHandler(new HandlerDescriptor(success, null, null));
120 AddHandler(new HandlerDescriptor(success, null, null));
123 return this;
121 return this;
124 }
122 }
125
123
126 public IPromise<T> On(Action handler, PromiseEventType events) {
124 public IPromise<T> On(Action handler, PromiseEventType events) {
127 AddHandler(new HandlerDescriptor(handler, events));
125 AddHandler(new HandlerDescriptor(handler, events));
128 return this;
126 return this;
129 }
127 }
130
128
131 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
129 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
132 AddHandler(new HandlerDescriptor(success, error, cancel));
130 AddHandler(new HandlerDescriptor(success, error, cancel));
133 return this;
131 return this;
134 }
132 }
135
133
136 public IPromise<T> On(Action success, Action<Exception> error) {
134 public IPromise<T> On(Action success, Action<Exception> error) {
137 AddHandler(new HandlerDescriptor(success, error, null));
135 AddHandler(new HandlerDescriptor(success, error, null));
138 return this;
136 return this;
139 }
137 }
140
138
141 public IPromise<T> On(Action success) {
139 public IPromise<T> On(Action success) {
142 AddHandler(new HandlerDescriptor(success, null, null));
140 AddHandler(new HandlerDescriptor(success, null, null));
143 return this;
141 return this;
144 }
142 }
145
143
146 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
144 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
147 AddHandler(new HandlerDescriptor(success, error, cancel));
145 AddHandler(new HandlerDescriptor(success, error, cancel));
148 return this;
146 return this;
149 }
147 }
150
148
151 IPromise IPromise.On(Action success, Action<Exception> error) {
149 IPromise IPromise.On(Action success, Action<Exception> error) {
152 AddHandler(new HandlerDescriptor(success, error, null));
150 AddHandler(new HandlerDescriptor(success, error, null));
153 return this;
151 return this;
154 }
152 }
155
153
156 IPromise IPromise.On(Action success) {
154 IPromise IPromise.On(Action success) {
157 AddHandler(new HandlerDescriptor(success, null, null));
155 AddHandler(new HandlerDescriptor(success, null, null));
158 return this;
156 return this;
159 }
157 }
160
158
161 IPromise IPromise.On(Action handler, PromiseEventType events) {
159 IPromise IPromise.On(Action handler, PromiseEventType events) {
162 AddHandler(new HandlerDescriptor(handler, events));
160 AddHandler(new HandlerDescriptor(handler, events));
163 return this;
161 return this;
164 }
162 }
165
163
166 public IPromise<T2> Cast<T2>() {
164 public IPromise<T2> Cast<T2>() {
167 return (IPromise<T2>)this;
165 return (IPromise<T2>)this;
168 }
166 }
169
167
170 #region implemented abstract members of AbstractPromise
168 #region implemented abstract members of AbstractPromise
171
169
172 protected override Signal GetResolveSignal() {
170 protected override Signal GetResolveSignal() {
173 var signal = new Signal();
171 var signal = new Signal();
174 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
172 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
175 return signal;
173 return signal;
176 }
174 }
177
175
178 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
176 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
179 switch (signal) {
177 switch (signal) {
180 case SUCCEEDED_STATE:
178 case SUCCEEDED_STATE:
181 handler.SignalSuccess(m_result);
179 handler.SignalSuccess(m_result);
182 break;
180 break;
183 case REJECTED_STATE:
181 case REJECTED_STATE:
184 handler.SignalError(Error);
182 handler.SignalError(Error);
185 break;
183 break;
186 case CANCELLED_STATE:
184 case CANCELLED_STATE:
187 handler.SignalCancel(CancellationReason);
185 handler.SignalCancel(CancellationReason);
188 break;
186 break;
189 default:
187 default:
190 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
188 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
191 }
189 }
192 }
190 }
193
191
194 #endregion
192 #endregion
195
193
196 T m_result;
194 T m_result;
197
195
198 protected void SetResult(T value) {
196 protected void SetResult(T value) {
199 if (BeginSetResult()) {
197 if (BeginSetResult()) {
200 m_result = value;
198 m_result = value;
201 EndSetResult();
199 EndSetResult();
202 }
200 }
203 }
201 }
204 }
202 }
205 }
203 }
206
204
@@ -1,36 +1,34
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class ActionChainTask : ActionChainTaskBase, IDeferred {
4 public class ActionChainTask : ActionChainTaskBase, IDeferred {
5 readonly Func<IPromise> m_task;
5 readonly Func<IPromise> m_task;
6
6
7 /// <summary>
7 /// <summary>
8 /// Initializes a new instance of the <see cref="Implab.ActionChainTask"/> class.
8 /// Initializes a new instance of the <see cref="Implab.ActionChainTask"/> class.
9 /// </summary>
9 /// </summary>
10 /// <param name="task">The operation which will be performed when the <see cref="Resolve()"/> is called.</param>
10 /// <param name="task">The operation which will be performed when the <see cref="Resolve()"/> is called.</param>
11 /// <param name="error">The error handler which will invoke when the <see cref="Reject(Exception)"/> is called or when the task fails with an error.</param>
11 /// <param name="error">The error handler which will invoke when the <see cref="Reject(Exception)"/> is called or when the task fails with an error.</param>
12 /// <param name="cancel">The cancellation handler.</param>
12 /// <param name="cancel">The cancellation handler.</param>
13 /// <param name="autoCancellable">If set to <c>true</c> will automatically accept
13 /// <param name="autoCancellable">If set to <c>true</c> will automatically accept
14 /// all cancel requests before the task is started with <see cref="Resolve()"/>,
14 /// all cancel requests before the task is started with <see cref="Resolve()"/>,
15 /// after that all requests are directed to the task.</param>
15 /// after that all requests are directed to the task.</param>
16 public ActionChainTask(Func<IPromise> task, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
16 public ActionChainTask(Func<IPromise> task, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
17 m_task = task;
17 m_task = task;
18 }
18 }
19
19
20 public void Resolve() {
20 public void Resolve() {
21 if (m_task != null && LockCancelation()) {
21 if (m_task != null && LockCancelation()) {
22 try {
22 try {
23 var p = m_task();
23 var p = m_task();
24 p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
24 p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
25 CancellationRequested(p.Cancel);
25 CancellationRequested(p.Cancel);
26 } catch (OperationCanceledException reason){
27 HandleCancelInternal(reason);
28 } catch(Exception err) {
26 } catch(Exception err) {
29 HandleErrorInternal(err);
27 SetErrorInternal(err);
30 }
28 }
31 }
29 }
32 }
30 }
33
31
34 }
32 }
35 }
33 }
36
34
@@ -1,62 +1,62
1 using System;
1 using System;
2 using System.Threading;
2 using System.Threading;
3
3
4 namespace Implab {
4 namespace Implab {
5 public class ActionChainTaskBase : AbstractTask {
5 public class ActionChainTaskBase : AbstractTask {
6 readonly Func<Exception, IPromise> m_error;
6 readonly Func<Exception, IPromise> m_error;
7 readonly Func<Exception, IPromise> m_cancel;
7 readonly Func<Exception, IPromise> m_cancel;
8
8
9 protected ActionChainTaskBase(Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) {
9 protected ActionChainTaskBase(Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) {
10 m_error = error;
10 m_error = error;
11 m_cancel = cancel;
11 m_cancel = cancel;
12 if (autoCancellable)
12 if (autoCancellable)
13 CancellationRequested(CancelOperation);
13 CancellationRequested(CancelOperation);
14 }
14 }
15
15
16 public void Reject(Exception error) {
16 public void Reject(Exception error) {
17 if (LockCancelation())
17 if (LockCancelation())
18 HandleErrorInternal(error);
18 HandleErrorInternal(error);
19 }
19 }
20
20
21 public override void CancelOperation(Exception reason) {
21 public override void CancelOperation(Exception reason) {
22 if (LockCancelation())
22 if (LockCancelation())
23 // отмена вызвана до начала выполнения задачи
23 // отмена вызвана до начала выполнения задачи
24 HandleCancelInternal(reason);
24 HandleCancelInternal(reason);
25 }
25 }
26
26
27 protected void HandleCancelInternal(Exception reason) {
27 protected void HandleCancelInternal(Exception reason) {
28 if (m_cancel != null) {
28 if (m_cancel != null) {
29 try {
29 try {
30 // вызываем обработчик отмены
30 // вызываем обработчик отмены
31 var p = m_cancel(reason);
31 var p = m_cancel(reason);
32 p.On(SetResult, HandleErrorInternal, SetCancelledInternal);
32 p.On(SetResult, HandleErrorInternal, SetCancelledInternal);
33 // сообщаем асинхронной операции, что клиент уже не хочет получать результат
33 // сообщаем асинхронной операции, что клиент уже не хочет получать результат
34 // т.е. если он инициировал отмену, задача отменилась, вызвался обрабочик отмены
34 // т.е. если он инициировал отмену, задача отменилась, вызвался обрабочик отмены
35 // отбработчику сообщили, что результат уже не нужен и уже сам обработчик решает
35 // отбработчику сообщили, что результат уже не нужен и уже сам обработчик решает
36 // отдавать ли результат или подтвердить отмену (или вернуть ошибку).
36 // отдавать ли результат или подтвердить отмену (или вернуть ошибку).
37 CancellationRequested(p.Cancel);
37 CancellationRequested(p.Cancel);
38 } catch (Exception err) {
38 } catch (Exception err) {
39 HandleErrorInternal(err);
39 SetErrorInternal(err);
40 }
40 }
41 } else {
41 } else {
42 HandleErrorInternal(reason ?? new OperationCanceledException());
42 SetCancelledInternal(reason);
43 }
43 }
44 }
44 }
45
45
46 protected void HandleErrorInternal(Exception error) {
46 protected void HandleErrorInternal(Exception error) {
47 if (m_error != null) {
47 if (m_error != null) {
48 try {
48 try {
49 var p = m_error(error);
49 var p = m_error(error);
50 p.On(SetResult, SetErrorInternal, SetCancelledInternal);
50 p.On(SetResult, SetErrorInternal, SetCancelledInternal);
51 CancellationRequested(p.Cancel);
51 CancellationRequested(p.Cancel);
52 } catch (Exception err) {
52 } catch (Exception err) {
53 SetErrorInternal(error);
53 SetErrorInternal(err);
54 }
54 }
55 } else {
55 } else {
56 SetErrorInternal(error);
56 SetErrorInternal(error);
57 }
57 }
58 }
58 }
59
59
60 }
60 }
61 }
61 }
62
62
@@ -1,27 +1,25
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class ActionChainTask<T> : ActionChainTaskBase, IDeferred<T> {
4 public class ActionChainTask<T> : ActionChainTaskBase, IDeferred<T> {
5 readonly Func<T, IPromise> m_task;
5 readonly Func<T, IPromise> m_task;
6
6
7 public ActionChainTask(Func<T, IPromise> task, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
7 public ActionChainTask(Func<T, IPromise> task, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
8 m_task = task;
8 m_task = task;
9 }
9 }
10
10
11 public void Resolve(T value) {
11 public void Resolve(T value) {
12 if (m_task != null && LockCancelation()) {
12 if (m_task != null && LockCancelation()) {
13 try {
13 try {
14 var p = m_task(value);
14 var p = m_task(value);
15 p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
15 p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
16 CancellationRequested(p.Cancel);
16 CancellationRequested(p.Cancel);
17 } catch (OperationCanceledException reason) {
18 HandleCancelInternal(reason);
19 } catch(Exception err) {
17 } catch(Exception err) {
20 HandleErrorInternal(err);
18 SetErrorInternal(err);
21 }
19 }
22 }
20 }
23 }
21 }
24
22
25 }
23 }
26 }
24 }
27
25
@@ -1,24 +1,22
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class ActionTask : ActionTaskBase, IDeferred {
4 public class ActionTask : ActionTaskBase, IDeferred {
5 readonly Action m_task;
5 readonly Action m_task;
6 public ActionTask(Action task, Action<Exception> error, Action<Exception> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
6 public ActionTask(Action task, Action<Exception> error, Action<Exception> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
7 m_task = task;
7 m_task = task;
8 }
8 }
9
9
10 public void Resolve() {
10 public void Resolve() {
11 if (m_task != null && LockCancelation()) {
11 if (m_task != null && LockCancelation()) {
12 try {
12 try {
13 m_task();
13 m_task();
14 SetResult();
14 SetResult();
15 } catch(OperationCanceledException reason) {
16 HandleCancelInternal(reason);
17 } catch(Exception err) {
15 } catch(Exception err) {
18 HandleErrorInternal(err);
16 SetErrorInternal(err);
19 }
17 }
20 }
18 }
21 }
19 }
22 }
20 }
23 }
21 }
24
22
@@ -1,53 +1,53
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class ActionTaskBase : AbstractTask {
4 public class ActionTaskBase : AbstractTask {
5 readonly Action<Exception> m_cancel;
5 readonly Action<Exception> m_cancel;
6 readonly Action<Exception> m_error;
6 readonly Action<Exception> m_error;
7
7
8 protected ActionTaskBase( Action<Exception> error, Action<Exception> cancel, bool autoCancellable) {
8 protected ActionTaskBase( Action<Exception> error, Action<Exception> cancel, bool autoCancellable) {
9 m_error = error;
9 m_error = error;
10 m_cancel = cancel;
10 m_cancel = cancel;
11 if (autoCancellable)
11 if (autoCancellable)
12 CancellationRequested(CancelOperation);
12 CancellationRequested(CancelOperation);
13 }
13 }
14
14
15 public void Reject(Exception error) {
15 public void Reject(Exception error) {
16 Safe.ArgumentNotNull(error, "error");
16 Safe.ArgumentNotNull(error, "error");
17 if (LockCancelation())
17 if (LockCancelation())
18 HandleErrorInternal(error);
18 HandleErrorInternal(error);
19 }
19 }
20
20
21 public override void CancelOperation(Exception reason) {
21 public override void CancelOperation(Exception reason) {
22 if (LockCancelation())
22 if (LockCancelation())
23 HandleCancelInternal(reason);
23 HandleCancelInternal(reason);
24 }
24 }
25
25
26 protected void HandleErrorInternal(Exception error) {
26 protected void HandleErrorInternal(Exception error) {
27 if (m_error != null) {
27 if (m_error != null) {
28 try {
28 try {
29 m_error(error);
29 m_error(error);
30 SetResult();
30 SetResult();
31 } catch(Exception err) {
31 } catch(Exception err) {
32 SetErrorInternal(err);
32 SetErrorInternal(err);
33 }
33 }
34 } else {
34 } else {
35 SetErrorInternal(error);
35 SetErrorInternal(error);
36 }
36 }
37 }
37 }
38
38
39 protected void HandleCancelInternal(Exception error) {
39 protected void HandleCancelInternal(Exception error) {
40 if (m_cancel != null) {
40 if (m_cancel != null) {
41 try {
41 try {
42 m_cancel(error);
42 m_cancel(error);
43 SetResult();
43 SetResult();
44 } catch(Exception err) {
44 } catch(Exception err) {
45 HandleErrorInternal(err);
45 SetErrorInternal(err);
46 }
46 }
47 } else {
47 } else {
48 HandleErrorInternal(error ?? new OperationCanceledException());
48 SetCancelledInternal(error);
49 }
49 }
50 }
50 }
51 }
51 }
52 }
52 }
53
53
@@ -1,24 +1,22
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class ActionTask<T> : ActionTaskBase, IDeferred<T> {
4 public class ActionTask<T> : ActionTaskBase, IDeferred<T> {
5 readonly Action<T> m_task;
5 readonly Action<T> m_task;
6 public ActionTask(Action<T> task, Action<Exception> error, Action<Exception> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
6 public ActionTask(Action<T> task, Action<Exception> error, Action<Exception> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
7 m_task = task;
7 m_task = task;
8 }
8 }
9
9
10 public void Resolve(T value) {
10 public void Resolve(T value) {
11 if (m_task != null && LockCancelation()) {
11 if (m_task != null && LockCancelation()) {
12 try {
12 try {
13 m_task(value);
13 m_task(value);
14 SetResult();
14 SetResult();
15 } catch(OperationCanceledException reason) {
16 HandleCancelInternal(reason);
17 } catch(Exception err) {
15 } catch(Exception err) {
18 HandleErrorInternal(err);
16 SetErrorInternal(err);
19 }
17 }
20 }
18 }
21 }
19 }
22 }
20 }
23 }
21 }
24
22
@@ -1,257 +1,264
1 using System;
1 using System;
2
2
3 namespace Implab.Components {
3 namespace Implab.Components {
4 public abstract class RunnableComponent : IDisposable, IRunnable, IInitializable {
4 public abstract class RunnableComponent : IDisposable, IRunnable, IInitializable {
5 enum Commands {
5 enum Commands {
6 Ok = 0,
6 Ok = 0,
7 Fail,
7 Fail,
8 Init,
8 Init,
9 Start,
9 Start,
10 Stop,
10 Stop,
11 Dispose,
11 Dispose,
12 Last = Dispose
12 Last = Dispose
13 }
13 }
14
14
15 class StateMachine {
15 class StateMachine {
16 static readonly ExecutionState[,] _transitions;
16 static readonly ExecutionState[,] _transitions;
17
17
18 static StateMachine() {
18 static StateMachine() {
19 _transitions = new ExecutionState[(int)ExecutionState.Last + 1, (int)Commands.Last + 1];
19 _transitions = new ExecutionState[(int)ExecutionState.Last + 1, (int)Commands.Last + 1];
20
20
21 Edge(ExecutionState.Created, ExecutionState.Initializing, Commands.Init);
21 Edge(ExecutionState.Created, ExecutionState.Initializing, Commands.Init);
22 Edge(ExecutionState.Created, ExecutionState.Disposed, Commands.Dispose);
22 Edge(ExecutionState.Created, ExecutionState.Disposed, Commands.Dispose);
23
23
24 Edge(ExecutionState.Initializing, ExecutionState.Ready, Commands.Ok);
24 Edge(ExecutionState.Initializing, ExecutionState.Ready, Commands.Ok);
25 Edge(ExecutionState.Initializing, ExecutionState.Failed, Commands.Fail);
25 Edge(ExecutionState.Initializing, ExecutionState.Failed, Commands.Fail);
26
26
27 Edge(ExecutionState.Ready, ExecutionState.Starting, Commands.Start);
27 Edge(ExecutionState.Ready, ExecutionState.Starting, Commands.Start);
28 Edge(ExecutionState.Ready, ExecutionState.Disposed, Commands.Dispose);
28 Edge(ExecutionState.Ready, ExecutionState.Disposed, Commands.Dispose);
29
29
30 Edge(ExecutionState.Starting, ExecutionState.Running, Commands.Ok);
30 Edge(ExecutionState.Starting, ExecutionState.Running, Commands.Ok);
31 Edge(ExecutionState.Starting, ExecutionState.Failed, Commands.Fail);
31 Edge(ExecutionState.Starting, ExecutionState.Failed, Commands.Fail);
32 Edge(ExecutionState.Starting, ExecutionState.Stopping, Commands.Stop);
32 Edge(ExecutionState.Starting, ExecutionState.Stopping, Commands.Stop);
33 Edge(ExecutionState.Starting, ExecutionState.Disposed, Commands.Dispose);
33 Edge(ExecutionState.Starting, ExecutionState.Disposed, Commands.Dispose);
34
34
35 Edge(ExecutionState.Running, ExecutionState.Failed, Commands.Fail);
35 Edge(ExecutionState.Running, ExecutionState.Failed, Commands.Fail);
36 Edge(ExecutionState.Running, ExecutionState.Stopping, Commands.Stop);
36 Edge(ExecutionState.Running, ExecutionState.Stopping, Commands.Stop);
37 Edge(ExecutionState.Running, ExecutionState.Disposed, Commands.Dispose);
37 Edge(ExecutionState.Running, ExecutionState.Disposed, Commands.Dispose);
38
38
39 Edge(ExecutionState.Stopping, ExecutionState.Failed, Commands.Fail);
39 Edge(ExecutionState.Stopping, ExecutionState.Failed, Commands.Fail);
40 Edge(ExecutionState.Stopping, ExecutionState.Disposed, Commands.Ok);
40 Edge(ExecutionState.Stopping, ExecutionState.Disposed, Commands.Ok);
41
41
42 Edge(ExecutionState.Failed, ExecutionState.Disposed, Commands.Dispose);
42 Edge(ExecutionState.Failed, ExecutionState.Disposed, Commands.Dispose);
43 }
43 }
44
44
45 static void Edge(ExecutionState s1, ExecutionState s2, Commands cmd) {
45 static void Edge(ExecutionState s1, ExecutionState s2, Commands cmd) {
46 _transitions[(int)s1, (int)cmd] = s2;
46 _transitions[(int)s1, (int)cmd] = s2;
47 }
47 }
48
48
49 public ExecutionState State {
49 public ExecutionState State {
50 get;
50 get;
51 private set;
51 private set;
52 }
52 }
53
53
54 public StateMachine(ExecutionState initial) {
54 public StateMachine(ExecutionState initial) {
55 State = initial;
55 State = initial;
56 }
56 }
57
57
58 public bool Move(Commands cmd) {
58 public bool Move(Commands cmd) {
59 var next = _transitions[(int)State, (int)cmd];
59 var next = _transitions[(int)State, (int)cmd];
60 if (next == ExecutionState.Undefined)
60 if (next == ExecutionState.Undefined)
61 return false;
61 return false;
62 State = next;
62 State = next;
63 return true;
63 return true;
64 }
64 }
65 }
65 }
66
66
67 IPromise m_pending;
67 IPromise m_pending;
68 Exception m_lastError;
68 Exception m_lastError;
69
69
70 readonly StateMachine m_stateMachine;
70 readonly StateMachine m_stateMachine;
71
71
72 protected RunnableComponent(bool initialized) {
72 protected RunnableComponent(bool initialized) {
73 m_stateMachine = new StateMachine(initialized ? ExecutionState.Ready : ExecutionState.Created);
73 m_stateMachine = new StateMachine(initialized ? ExecutionState.Ready : ExecutionState.Created);
74 }
74 }
75
75
76 protected virtual int DisposeTimeout {
76 protected virtual int DisposeTimeout {
77 get {
77 get {
78 return 10000;
78 return 10000;
79 }
79 }
80 }
80 }
81
81
82 void ThrowInvalidCommand(Commands cmd) {
82 void ThrowInvalidCommand(Commands cmd) {
83 if (m_stateMachine.State == ExecutionState.Disposed)
83 if (m_stateMachine.State == ExecutionState.Disposed)
84 throw new ObjectDisposedException(ToString());
84 throw new ObjectDisposedException(ToString());
85
85
86 throw new InvalidOperationException(String.Format("Commnd {0} is not allowed in the state {1}", cmd, m_stateMachine.State));
86 throw new InvalidOperationException(String.Format("Commnd {0} is not allowed in the state {1}", cmd, m_stateMachine.State));
87 }
87 }
88
88
89 void Move(Commands cmd) {
89 void Move(Commands cmd) {
90 if (!m_stateMachine.Move(cmd))
90 if (!m_stateMachine.Move(cmd))
91 ThrowInvalidCommand(cmd);
91 ThrowInvalidCommand(cmd);
92 }
92 }
93
93
94 void Invoke(Commands cmd, Action action) {
94 void Invoke(Commands cmd, Action action) {
95 lock (m_stateMachine)
95 lock (m_stateMachine)
96 Move(cmd);
96 Move(cmd);
97
97
98 try {
98 try {
99 action();
99 action();
100 lock(m_stateMachine)
100 lock(m_stateMachine)
101 Move(Commands.Ok);
101 Move(Commands.Ok);
102
102
103 } catch (Exception err) {
103 } catch (Exception err) {
104 lock (m_stateMachine) {
104 lock (m_stateMachine) {
105 Move(Commands.Fail);
105 Move(Commands.Fail);
106 m_lastError = err;
106 m_lastError = err;
107 }
107 }
108 throw;
108 throw;
109 }
109 }
110 }
110 }
111
111
112 IPromise InvokeAsync(Commands cmd, Func<IPromise> action, Action<IPromise, IDeferred> chain) {
112 IPromise InvokeAsync(Commands cmd, Func<IPromise> action, Action<IPromise, IDeferred> chain) {
113 IPromise promise = null;
113 IPromise promise = null;
114 IPromise prev;
114 IPromise prev;
115
115
116 var task = new ActionChainTask(action, null, null, true);
116 var task = new ActionChainTask(action, null, null, true);
117
117
118 lock (m_stateMachine) {
118 lock (m_stateMachine) {
119 Move(cmd);
119 Move(cmd);
120
120
121 prev = m_pending;
121 prev = m_pending;
122
122
123 Action<Exception> errorOrCancel = e => {
124 if (e == null)
125 e = new OperationCanceledException();
126
127 lock (m_stateMachine) {
128 if (m_pending == promise) {
129 Move(Commands.Fail);
130 m_pending = null;
131 m_lastError = e;
132 }
133 }
134 throw new PromiseTransientException(e);
135 };
136
123 promise = task.Then(
137 promise = task.Then(
124 () => {
138 () => {
125 lock(m_stateMachine) {
139 lock(m_stateMachine) {
126 if (m_pending == promise) {
140 if (m_pending == promise) {
127 Move(Commands.Ok);
141 Move(Commands.Ok);
128 m_pending = null;
142 m_pending = null;
129 }
143 }
130 }
144 }
131 }, e => {
145 },
132 lock(m_stateMachine) {
146 errorOrCancel,
133 if (m_pending == promise) {
147 errorOrCancel
134 Move(Commands.Fail);
135 m_pending = null;
136 m_lastError = e;
137 }
138 }
139 throw new PromiseTransientException(e);
140 }
141 );
148 );
142
149
143 m_pending = promise;
150 m_pending = promise;
144 }
151 }
145
152
146 if (prev == null)
153 if (prev == null)
147 task.Resolve();
154 task.Resolve();
148 else
155 else
149 chain(prev, task);
156 chain(prev, task);
150
157
151 return promise;
158 return promise;
152 }
159 }
153
160
154
161
155 #region IInitializable implementation
162 #region IInitializable implementation
156
163
157 public void Init() {
164 public void Init() {
158 Invoke(Commands.Init, OnInitialize);
165 Invoke(Commands.Init, OnInitialize);
159 }
166 }
160
167
161 protected virtual void OnInitialize() {
168 protected virtual void OnInitialize() {
162 }
169 }
163
170
164 #endregion
171 #endregion
165
172
166 #region IRunnable implementation
173 #region IRunnable implementation
167
174
168 public IPromise Start() {
175 public IPromise Start() {
169 return InvokeAsync(Commands.Start, OnStart, null);
176 return InvokeAsync(Commands.Start, OnStart, null);
170 }
177 }
171
178
172 protected virtual IPromise OnStart() {
179 protected virtual IPromise OnStart() {
173 return Promise.SUCCESS;
180 return Promise.SUCCESS;
174 }
181 }
175
182
176 public IPromise Stop() {
183 public IPromise Stop() {
177 return InvokeAsync(Commands.Stop, OnStop, StopPending).Then(Dispose);
184 return InvokeAsync(Commands.Stop, OnStop, StopPending).Then(Dispose);
178 }
185 }
179
186
180 protected virtual IPromise OnStop() {
187 protected virtual IPromise OnStop() {
181 return Promise.SUCCESS;
188 return Promise.SUCCESS;
182 }
189 }
183
190
184 /// <summary>
191 /// <summary>
185 /// Stops the current operation if one exists.
192 /// Stops the current operation if one exists.
186 /// </summary>
193 /// </summary>
187 /// <param name="current">Current.</param>
194 /// <param name="current">Current.</param>
188 /// <param name="stop">Stop.</param>
195 /// <param name="stop">Stop.</param>
189 protected virtual void StopPending(IPromise current, IDeferred stop) {
196 protected virtual void StopPending(IPromise current, IDeferred stop) {
190 if (current == null) {
197 if (current == null) {
191 stop.Resolve();
198 stop.Resolve();
192 } else {
199 } else {
193 // связваем текущую операцию с операцией остановки
200 // связваем текущую операцию с операцией остановки
194 current.On(
201 current.On(
195 stop.Resolve, // если текущая операция заверщилась, то можно начинать остановку
202 stop.Resolve, // если текущая операция заверщилась, то можно начинать остановку
196 stop.Reject, // если текущая операция дала ошибку - то все плохо, нельзя продолжать
203 stop.Reject, // если текущая операция дала ошибку - то все плохо, нельзя продолжать
197 e => stop.Resolve() // если текущая отменилась, то можно начинать остановку
204 e => stop.Resolve() // если текущая отменилась, то можно начинать остановку
198 );
205 );
199 // посылаем текущей операции сигнал остановки
206 // посылаем текущей операции сигнал остановки
200 current.Cancel();
207 current.Cancel();
201 }
208 }
202 }
209 }
203
210
204 public ExecutionState State {
211 public ExecutionState State {
205 get {
212 get {
206 return m_stateMachine.State;
213 return m_stateMachine.State;
207 }
214 }
208 }
215 }
209
216
210 public Exception LastError {
217 public Exception LastError {
211 get {
218 get {
212 return m_lastError;
219 return m_lastError;
213 }
220 }
214 }
221 }
215
222
216 #endregion
223 #endregion
217
224
218 #region IDisposable implementation
225 #region IDisposable implementation
219
226
220 public void Dispose() {
227 public void Dispose() {
221 IPromise pending;
228 IPromise pending;
222 lock (m_stateMachine) {
229 lock (m_stateMachine) {
223 if (m_stateMachine.State == ExecutionState.Disposed)
230 if (m_stateMachine.State == ExecutionState.Disposed)
224 return;
231 return;
225
232
226 Move(Commands.Dispose);
233 Move(Commands.Dispose);
227
234
228 GC.SuppressFinalize(this);
235 GC.SuppressFinalize(this);
229
236
230 pending = m_pending;
237 pending = m_pending;
231 m_pending = null;
238 m_pending = null;
232 }
239 }
233 if (pending != null) {
240 if (pending != null) {
234 pending.Cancel();
241 pending.Cancel();
235 pending.Timeout(DisposeTimeout).On(
242 pending.Timeout(DisposeTimeout).On(
236 () => Dispose(true, null),
243 () => Dispose(true, null),
237 err => Dispose(true, err),
244 err => Dispose(true, err),
238 reason => Dispose(true, new OperationCanceledException("The operation is cancelled", reason))
245 reason => Dispose(true, new OperationCanceledException("The operation is cancelled", reason))
239 );
246 );
240 } else {
247 } else {
241 Dispose(true, m_lastError);
248 Dispose(true, m_lastError);
242 }
249 }
243 }
250 }
244
251
245 ~RunnableComponent() {
252 ~RunnableComponent() {
246 Dispose(false, null);
253 Dispose(false, null);
247 }
254 }
248
255
249 #endregion
256 #endregion
250
257
251 protected virtual void Dispose(bool disposing, Exception lastError) {
258 protected virtual void Dispose(bool disposing, Exception lastError) {
252
259
253 }
260 }
254
261
255 }
262 }
256 }
263 }
257
264
@@ -1,26 +1,24
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class FuncChainTask<TResult> : FuncChainTaskBase<TResult>, IDeferred {
4 public class FuncChainTask<TResult> : FuncChainTaskBase<TResult>, IDeferred {
5 readonly Func<IPromise<TResult>> m_task;
5 readonly Func<IPromise<TResult>> m_task;
6
6
7 public FuncChainTask(Func<IPromise<TResult>> task, Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable)
7 public FuncChainTask(Func<IPromise<TResult>> task, Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable)
8 : base(error, cancel, autoCancellable) {
8 : base(error, cancel, autoCancellable) {
9 m_task = task;
9 m_task = task;
10 }
10 }
11
11
12 public void Resolve() {
12 public void Resolve() {
13 if (m_task != null && LockCancelation()) {
13 if (m_task != null && LockCancelation()) {
14 try {
14 try {
15 var operation = m_task();
15 var operation = m_task();
16 operation.On(SetResult, HandleErrorInternal, HandleCancelInternal);
16 operation.On(SetResult, HandleErrorInternal, HandleCancelInternal);
17 CancellationRequested(operation.Cancel);
17 CancellationRequested(operation.Cancel);
18 } catch (OperationCanceledException reason) {
19 HandleCancelInternal(reason);
20 } catch (Exception err) {
18 } catch (Exception err) {
21 HandleErrorInternal(err);
19 SetErrorInternal(err);
22 }
20 }
23 }
21 }
24 }
22 }
25 }
23 }
26 } No newline at end of file
24 }
@@ -1,54 +1,54
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class FuncChainTaskBase<TResult> : AbstractTask<TResult> {
4 public class FuncChainTaskBase<TResult> : AbstractTask<TResult> {
5 readonly Func<Exception, IPromise<TResult>> m_error;
5 readonly Func<Exception, IPromise<TResult>> m_error;
6 readonly Func<Exception, IPromise<TResult>> m_cancel;
6 readonly Func<Exception, IPromise<TResult>> m_cancel;
7
7
8 protected FuncChainTaskBase( Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable) {
8 protected FuncChainTaskBase( Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable) {
9 m_error = error;
9 m_error = error;
10 m_cancel = cancel;
10 m_cancel = cancel;
11 if (autoCancellable)
11 if (autoCancellable)
12 CancellationRequested(CancelOperation);
12 CancellationRequested(CancelOperation);
13 }
13 }
14
14
15 public void Reject(Exception error) {
15 public void Reject(Exception error) {
16 if (LockCancelation())
16 if (LockCancelation())
17 HandleErrorInternal(error);
17 HandleErrorInternal(error);
18 }
18 }
19
19
20 public override void CancelOperation(Exception reason) {
20 public override void CancelOperation(Exception reason) {
21 if (LockCancelation())
21 if (LockCancelation())
22 HandleCancelInternal(reason);
22 HandleCancelInternal(reason);
23 }
23 }
24
24
25 protected void HandleErrorInternal(Exception error) {
25 protected void HandleErrorInternal(Exception error) {
26 if (m_error != null) {
26 if (m_error != null) {
27 try {
27 try {
28 var p = m_error(error);
28 var p = m_error(error);
29 p.On(SetResult, SetErrorInternal, SetCancelledInternal);
29 p.On(SetResult, SetErrorInternal, SetCancelledInternal);
30 CancellationRequested(p.Cancel);
30 CancellationRequested(p.Cancel);
31 } catch(Exception err) {
31 } catch(Exception err) {
32 SetErrorInternal(err);
32 SetErrorInternal(err);
33 }
33 }
34 } else {
34 } else {
35 SetErrorInternal(error);
35 SetErrorInternal(error);
36 }
36 }
37 }
37 }
38
38
39 protected void HandleCancelInternal(Exception reason) {
39 protected void HandleCancelInternal(Exception reason) {
40 if (m_cancel != null) {
40 if (m_cancel != null) {
41 try {
41 try {
42 var p = m_cancel(reason);
42 var p = m_cancel(reason);
43 p.On(SetResult, HandleErrorInternal, SetCancelledInternal);
43 p.On(SetResult, HandleErrorInternal, SetCancelledInternal);
44 CancellationRequested(p.Cancel);
44 CancellationRequested(p.Cancel);
45 } catch (Exception err) {
45 } catch (Exception err) {
46 HandleErrorInternal(err);
46 SetErrorInternal(err);
47 }
47 }
48 } else {
48 } else {
49 HandleErrorInternal(reason ?? new OperationCanceledException());
49 SetCancelledInternal(reason);
50 }
50 }
51 }
51 }
52 }
52 }
53 }
53 }
54
54
@@ -1,25 +1,23
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class FuncChainTask<TArg,TResult> : FuncChainTaskBase<TResult>, IDeferred<TArg> {
4 public class FuncChainTask<TArg,TResult> : FuncChainTaskBase<TResult>, IDeferred<TArg> {
5 readonly Func<TArg, IPromise<TResult>> m_task;
5 readonly Func<TArg, IPromise<TResult>> m_task;
6
6
7 public FuncChainTask(Func<TArg, IPromise<TResult>> task, Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable) : base(error, cancel, autoCancellable){
7 public FuncChainTask(Func<TArg, IPromise<TResult>> task, Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable) : base(error, cancel, autoCancellable){
8 m_task = task;
8 m_task = task;
9 }
9 }
10
10
11 public void Resolve(TArg value) {
11 public void Resolve(TArg value) {
12 if (m_task != null && LockCancelation()) {
12 if (m_task != null && LockCancelation()) {
13 try {
13 try {
14 var operation = m_task(value);
14 var operation = m_task(value);
15 operation.On(SetResult, HandleErrorInternal, SetCancelled);
15 operation.On(SetResult, HandleErrorInternal, SetCancelled);
16 CancellationRequested(operation.Cancel);
16 CancellationRequested(operation.Cancel);
17 } catch (OperationCanceledException reason) {
18 HandleCancelInternal(reason);
19 } catch (Exception err) {
17 } catch (Exception err) {
20 HandleErrorInternal(err);
18 SetErrorInternal(err);
21 }
19 }
22 }
20 }
23 }
21 }
24 }
22 }
25 } No newline at end of file
23 }
@@ -1,25 +1,23
1 using System;
1 using System;
2 using System.Threading;
2 using System.Threading;
3
3
4 namespace Implab {
4 namespace Implab {
5 public class FuncTask<T> : FuncTaskBase<T>, IDeferred {
5 public class FuncTask<T> : FuncTaskBase<T>, IDeferred {
6 readonly Func<T> m_task;
6 readonly Func<T> m_task;
7
7
8 public FuncTask(Func<T> task, Func<Exception, T> error, Func<Exception, T> cancel, bool autoCancellable) : base(error, cancel, autoCancellable) {
8 public FuncTask(Func<T> task, Func<Exception, T> error, Func<Exception, T> cancel, bool autoCancellable) : base(error, cancel, autoCancellable) {
9 m_task = task;
9 m_task = task;
10 }
10 }
11
11
12 public void Resolve() {
12 public void Resolve() {
13 if (m_task != null && LockCancelation()) {
13 if (m_task != null && LockCancelation()) {
14 try {
14 try {
15 SetResult(m_task());
15 SetResult(m_task());
16 } catch(OperationCanceledException reason) {
17 HandleCancelInternal(reason);
18 } catch(Exception err) {
16 } catch(Exception err) {
19 HandleErrorInternal(err);
17 SetErrorInternal(err);
20 }
18 }
21 }
19 }
22 }
20 }
23 }
21 }
24 }
22 }
25
23
@@ -1,52 +1,52
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class FuncTaskBase<TResult> : AbstractTask<TResult> {
4 public class FuncTaskBase<TResult> : AbstractTask<TResult> {
5 readonly Func<Exception, TResult> m_cancel;
5 readonly Func<Exception, TResult> m_cancel;
6 readonly Func<Exception, TResult> m_error;
6 readonly Func<Exception, TResult> m_error;
7
7
8 protected FuncTaskBase( Func<Exception, TResult> error, Func<Exception, TResult> cancel, bool autoCancellable) {
8 protected FuncTaskBase( Func<Exception, TResult> error, Func<Exception, TResult> cancel, bool autoCancellable) {
9 m_error = error;
9 m_error = error;
10 m_cancel = cancel;
10 m_cancel = cancel;
11 if (autoCancellable)
11 if (autoCancellable)
12 CancellationRequested(CancelOperation);
12 CancellationRequested(CancelOperation);
13 }
13 }
14
14
15 public void Reject(Exception error) {
15 public void Reject(Exception error) {
16 Safe.ArgumentNotNull(error, "error");
16 Safe.ArgumentNotNull(error, "error");
17 if (LockCancelation())
17 if (LockCancelation())
18 HandleErrorInternal(error);
18 HandleErrorInternal(error);
19 }
19 }
20
20
21 protected void HandleErrorInternal(Exception error) {
21 protected void HandleErrorInternal(Exception error) {
22 if (m_error != null) {
22 if (m_error != null) {
23 try {
23 try {
24 SetResult(m_error(error));
24 SetResult(m_error(error));
25 } catch(Exception err) {
25 } catch(Exception err) {
26 SetErrorInternal(err);
26 SetErrorInternal(err);
27 }
27 }
28 } else {
28 } else {
29 SetErrorInternal(error);
29 SetErrorInternal(error);
30 }
30 }
31 }
31 }
32
32
33 public override void CancelOperation(Exception reason) {
33 public override void CancelOperation(Exception reason) {
34 if (LockCancelation())
34 if (LockCancelation())
35 HandleCancelInternal(reason);
35 HandleCancelInternal(reason);
36 }
36 }
37
37
38 protected void HandleCancelInternal(Exception reason) {
38 protected void HandleCancelInternal(Exception reason) {
39 if (m_cancel != null) {
39 if (m_cancel != null) {
40 try {
40 try {
41 SetResult(m_cancel(reason));
41 SetResult(m_cancel(reason));
42 } catch (Exception err) {
42 } catch (Exception err) {
43 HandleErrorInternal(err);
43 SetErrorInternal(err);
44 }
44 }
45 } else {
45 } else {
46 HandleErrorInternal(reason ?? new OperationCanceledException());
46 SetCancelledInternal(reason);
47 }
47 }
48 }
48 }
49
49
50 }
50 }
51 }
51 }
52
52
@@ -1,24 +1,22
1 using System;
1 using System;
2
2
3 namespace Implab {
3 namespace Implab {
4 public class FuncTask<TArg, TResult> : FuncTaskBase<TResult>, IDeferred<TArg> {
4 public class FuncTask<TArg, TResult> : FuncTaskBase<TResult>, IDeferred<TArg> {
5 readonly Func<TArg, TResult> m_task;
5 readonly Func<TArg, TResult> m_task;
6
6
7 public FuncTask(Func<TArg, TResult> task, Func<Exception, TResult> error,Func<Exception, TResult> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
7 public FuncTask(Func<TArg, TResult> task, Func<Exception, TResult> error,Func<Exception, TResult> cancel, bool autoCancellable) : base(error,cancel, autoCancellable) {
8 m_task = task;
8 m_task = task;
9 }
9 }
10
10
11 public void Resolve(TArg value) {
11 public void Resolve(TArg value) {
12 if (m_task != null && LockCancelation()) {
12 if (m_task != null && LockCancelation()) {
13 try {
13 try {
14 SetResult(m_task(value));
14 SetResult(m_task(value));
15 } catch(OperationCanceledException reason) {
16 HandleCancelInternal(reason);
17 } catch(Exception err) {
15 } catch(Exception err) {
18 HandleErrorInternal(err);
16 SetErrorInternal(err);
19 }
17 }
20 }
18 }
21 }
19 }
22 }
20 }
23 }
21 }
24
22
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now