##// END OF EJS Templates
working on cancelation and error handling
cin -
r186:75103928da09 ref20160224
parent child
Show More
@@ -77,19 +77,14 namespace Implab {
77 /// <param name="error">Исключение возникшее при выполнении операции</param>
77 /// <param name="error">Исключение возникшее при выполнении операции</param>
78 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
78 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
79 protected void SetError(Exception error) {
79 protected void SetError(Exception error) {
80 while (error is PromiseTransientException)
81 error = error.InnerException;
82
83 var isCancel = error is OperationCanceledException;
84
85 if (BeginTransit()) {
80 if (BeginTransit()) {
86 m_error = isCancel ? error.InnerException : error;
81 m_error = error;
87 CompleteTransit(isCancel ? CANCELLED_STATE : REJECTED_STATE);
82 CompleteTransit(REJECTED_STATE);
88
83
89 Signal();
84 Signal();
90 } else {
85 } else {
91 WaitTransition();
86 WaitTransition();
92 if (!isCancel || m_state == SUCCEEDED_STATE)
87 if (m_state == SUCCEEDED_STATE)
93 throw new InvalidOperationException("The promise is already resolved");
88 throw new InvalidOperationException("The promise is already resolved");
94 }
89 }
95 }
90 }
@@ -140,11 +135,11 namespace Implab {
140 case SUCCEEDED_STATE:
135 case SUCCEEDED_STATE:
141 return;
136 return;
142 case CANCELLED_STATE:
137 case CANCELLED_STATE:
143 throw new OperationCanceledException();
138 throw new OperationCanceledException("The operation has been cancelled", m_error);
144 case REJECTED_STATE:
139 case REJECTED_STATE:
145 throw new TargetInvocationException(m_error);
140 throw new TargetInvocationException(m_error);
146 default:
141 default:
147 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
142 throw new ApplicationException(String.Format("The promise state {0} is invalid", m_state));
148 }
143 }
149 }
144 }
150 #endregion
145 #endregion
@@ -134,8 +134,8 namespace Implab {
134 }
134 }
135
135
136 protected void SetResult() {
136 protected void SetResult() {
137 BeginSetResult();
137 if(BeginSetResult())
138 EndSetResult();
138 EndSetResult();
139 }
139 }
140 }
140 }
141 }
141 }
@@ -20,34 +20,51 namespace Implab {
20 HandleErrorInternal(error);
20 HandleErrorInternal(error);
21 }
21 }
22
22
23
24
25 public override void CancelOperation(Exception reason) {
23 public override void CancelOperation(Exception reason) {
26 if (LockCancelation()) {
24 if (LockCancelation()) {
25 if (!(reason is OperationCanceledException))
26 reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException();
27
27 if (m_cancel != null) {
28 if (m_cancel != null) {
28 try {
29 try {
29 m_cancel(reason).On(SetResult, SetError, SetCancelled);
30 m_cancel(reason).On(SetResult, HandleErrorInternal, HandleCancelInternal);
30 } catch (Exception err) {
31 } catch (Exception err) {
31 HandleErrorInternal(err);
32 HandleErrorInternal(err);
32 }
33 }
33 } else {
34 } else {
34 SetCancelled(reason);
35 HandleErrorInternal(reason);
35 }
36 }
36 }
37 }
37 }
38 }
38
39
39 protected void HandleErrorInternal(Exception error) {
40 void HandleCancelInternal(Exception reason) {
41 if (!(reason is OperationCanceledException))
42 reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException();
43 HandleErrorInternal(reason);
44 }
45
46 void HandleErrorInternal(Exception error) {
40 if (m_error != null) {
47 if (m_error != null) {
41 try {
48 try {
42 var p = m_error(error);
49 var p = m_error(error);
43 p.On(SetResult,SetError,SetCancelled);
50 p.On(SetResult, SetError, SetCancelled);
44 CancellationRequested(p.Cancel);
51 CancellationRequested(p.Cancel);
45 } catch (Exception err) {
52 } catch (Exception err) {
46 SetError(err);
53 error = err;
47 }
54 }
48 } else {
55 } else {
56 SetErrorInternal(error);
57 }
58 }
59
60 void SetErrorInternal(Exception error) {
61 while (error is PromiseTransientException)
62 error = error.InnerException;
63
64 if (error is OperationCanceledException)
65 SetCancelled(error);
66 else
49 SetError(error);
67 SetError(error);
50 }
51 }
68 }
52
69
53 protected bool LockCancelation() {
70 protected bool LockCancelation() {
@@ -139,14 +139,7 namespace Implab.Components {
139 throw new PromiseTransientException(e);
139 throw new PromiseTransientException(e);
140 },
140 },
141 r => {
141 r => {
142 lock(m_stateMachine) {
142 // handle cancellation as exception
143 if (m_pending == promise) {
144 Move(Commands.Fail);
145 m_pending = null;
146 m_lastError = new OperationCanceledException("The operation has been cancelled", r);
147 }
148
149 }
150 throw new OperationCanceledException("The operation has been cancelled", r);
143 throw new OperationCanceledException("The operation has been cancelled", r);
151 }
144 }
152 );
145 );
@@ -201,7 +194,7 namespace Implab.Components {
201 if (current == null) {
194 if (current == null) {
202 stop.Resolve();
195 stop.Resolve();
203 } else {
196 } else {
204 current.On(stop.Resolve, stop.Reject, stop.CancelOperation);
197 current.On(stop.Resolve, stop.Reject, e => stop.Resolve());
205 current.Cancel();
198 current.Cancel();
206 }
199 }
207 }
200 }
General Comments 0
You need to be logged in to leave comments. Login now