comparison Implab/AbstractPromise.cs @ 138:f75cfa58e3d4 v2

added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
author cin
date Tue, 17 Feb 2015 18:16:26 +0300
parents 671f60cd0250
children 16f926ee499d
comparison
equal deleted inserted replaced
137:238e15580926 138:f75cfa58e3d4
66 /// </remarks> 66 /// </remarks>
67 /// <param name="error">Исключение возникшее при выполнении операции</param> 67 /// <param name="error">Исключение возникшее при выполнении операции</param>
68 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> 68 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
69 protected void SetError(Exception error) { 69 protected void SetError(Exception error) {
70 if (BeginTransit()) { 70 if (BeginTransit()) {
71 m_error = error is PromiseTransientException ? error.InnerException : error; 71 if (error is OperationCanceledException) {
72 CompleteTransit(REJECTED_STATE); 72 CompleteTransit(CANCELLED_STATE);
73 OnError(); 73 m_error = error.InnerException;
74 OnCancelled();
75 } else {
76 m_error = error is PromiseTransientException ? error.InnerException : error;
77 CompleteTransit(REJECTED_STATE);
78 OnError();
79 }
74 } else { 80 } else {
75 WaitTransition(); 81 WaitTransition();
76 if (m_state == SUCCEEDED_STATE) 82 if (m_state == SUCCEEDED_STATE)
77 throw new InvalidOperationException("The promise is already resolved"); 83 throw new InvalidOperationException("The promise is already resolved");
78 } 84 }
80 86
81 /// <summary> 87 /// <summary>
82 /// Отменяет операцию, если это возможно. 88 /// Отменяет операцию, если это возможно.
83 /// </summary> 89 /// </summary>
84 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> 90 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks>
85 protected void SetCancelled() { 91 protected void SetCancelled(Exception reason) {
86 if (BeginTransit()) { 92 if (BeginTransit()) {
93 m_error = reason;
87 CompleteTransit(CANCELLED_STATE); 94 CompleteTransit(CANCELLED_STATE);
88 OnCancelled(); 95 OnCancelled();
89 } 96 }
90 } 97 }
91 98
92 protected abstract void SignalSuccess(THandler handler); 99 protected abstract void SignalSuccess(THandler handler);
93 100
94 protected abstract void SignalError(THandler handler, Exception error); 101 protected abstract void SignalError(THandler handler, Exception error);
95 102
96 protected abstract void SignalCancelled(THandler handler); 103 protected abstract void SignalCancelled(THandler handler, Exception reason);
97 104
98 void OnSuccess() { 105 void OnSuccess() {
99 var hp = m_handlerPointer; 106 var hp = m_handlerPointer;
100 var slot = hp +1 ; 107 var slot = hp +1 ;
101 while (slot < m_handlersCommited) { 108 while (slot < m_handlersCommited) {
135 void OnCancelled() { 142 void OnCancelled() {
136 var hp = m_handlerPointer; 143 var hp = m_handlerPointer;
137 var slot = hp +1 ; 144 var slot = hp +1 ;
138 while (slot < m_handlersCommited) { 145 while (slot < m_handlersCommited) {
139 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { 146 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
140 SignalCancelled(m_handlers[slot]); 147 SignalCancelled(m_handlers[slot], m_error);
141 } 148 }
142 hp = m_handlerPointer; 149 hp = m_handlerPointer;
143 slot = hp +1 ; 150 slot = hp +1 ;
144 } 151 }
145 152
146 if (m_extraHandlers != null) { 153 if (m_extraHandlers != null) {
147 THandler handler; 154 THandler handler;
148 while (m_extraHandlers.TryDequeue(out handler)) 155 while (m_extraHandlers.TryDequeue(out handler))
149 SignalCancelled(handler); 156 SignalCancelled(handler, m_error);
150 } 157 }
151 } 158 }
152 159
153 #endregion 160 #endregion
154 161
239 switch (m_state) { 246 switch (m_state) {
240 case SUCCEEDED_STATE: 247 case SUCCEEDED_STATE:
241 SignalSuccess(handler); 248 SignalSuccess(handler);
242 break; 249 break;
243 case CANCELLED_STATE: 250 case CANCELLED_STATE:
244 SignalCancelled(handler); 251 SignalCancelled(handler, m_error);
245 break; 252 break;
246 case REJECTED_STATE: 253 case REJECTED_STATE:
247 SignalError(handler, m_error); 254 SignalError(handler, m_error);
248 break; 255 break;
249 default: 256 default:
280 #endregion 287 #endregion
281 288
282 #region ICancellable implementation 289 #region ICancellable implementation
283 290
284 public void Cancel() { 291 public void Cancel() {
285 SetCancelled(); 292 SetCancelled(null);
286 } 293 }
287 294
288 #endregion 295 public void Cancel(Exception reason) {
296 SetCancelled(reason);
297 }
298
299 #endregion
300
301 public Exception Error {
302 get {
303 return m_error;
304 }
305 }
289 } 306 }
290 } 307 }
291 308