Mercurial > pub > ImplabNet
diff 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 |
line wrap: on
line diff
--- a/Implab/AbstractPromise.cs Mon Feb 16 17:48:39 2015 +0300 +++ b/Implab/AbstractPromise.cs Tue Feb 17 18:16:26 2015 +0300 @@ -68,9 +68,15 @@ /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> protected void SetError(Exception error) { if (BeginTransit()) { - m_error = error is PromiseTransientException ? error.InnerException : error; - CompleteTransit(REJECTED_STATE); - OnError(); + if (error is OperationCanceledException) { + CompleteTransit(CANCELLED_STATE); + m_error = error.InnerException; + OnCancelled(); + } else { + m_error = error is PromiseTransientException ? error.InnerException : error; + CompleteTransit(REJECTED_STATE); + OnError(); + } } else { WaitTransition(); if (m_state == SUCCEEDED_STATE) @@ -82,8 +88,9 @@ /// Отменяет операцию, если это возможно. /// </summary> /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> - protected void SetCancelled() { + protected void SetCancelled(Exception reason) { if (BeginTransit()) { + m_error = reason; CompleteTransit(CANCELLED_STATE); OnCancelled(); } @@ -93,7 +100,7 @@ protected abstract void SignalError(THandler handler, Exception error); - protected abstract void SignalCancelled(THandler handler); + protected abstract void SignalCancelled(THandler handler, Exception reason); void OnSuccess() { var hp = m_handlerPointer; @@ -137,7 +144,7 @@ var slot = hp +1 ; while (slot < m_handlersCommited) { if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { - SignalCancelled(m_handlers[slot]); + SignalCancelled(m_handlers[slot], m_error); } hp = m_handlerPointer; slot = hp +1 ; @@ -146,7 +153,7 @@ if (m_extraHandlers != null) { THandler handler; while (m_extraHandlers.TryDequeue(out handler)) - SignalCancelled(handler); + SignalCancelled(handler, m_error); } } @@ -241,7 +248,7 @@ SignalSuccess(handler); break; case CANCELLED_STATE: - SignalCancelled(handler); + SignalCancelled(handler, m_error); break; case REJECTED_STATE: SignalError(handler, m_error); @@ -282,10 +289,20 @@ #region ICancellable implementation public void Cancel() { - SetCancelled(); + SetCancelled(null); + } + + public void Cancel(Exception reason) { + SetCancelled(reason); } #endregion + + public Exception Error { + get { + return m_error; + } + } } }