Mercurial > pub > ImplabNet
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 |
