Mercurial > pub > ImplabNet
changeset 186:75103928da09 ref20160224
working on cancelation and error handling
author | cin |
---|---|
date | Tue, 19 Apr 2016 00:50:14 +0300 |
parents | 822aab37b107 |
children | dd4a3590f9c6 |
files | Implab/AbstractEvent.cs Implab/AbstractPromise.cs Implab/ActionChainTaskBase.cs Implab/Components/RunnableComponent.cs |
diffstat | 4 files changed, 34 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab/AbstractEvent.cs Mon Apr 18 16:41:17 2016 +0300 +++ b/Implab/AbstractEvent.cs Tue Apr 19 00:50:14 2016 +0300 @@ -77,19 +77,14 @@ /// <param name="error">Исключение возникшее при выполнении операции</param> /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> protected void SetError(Exception error) { - while (error is PromiseTransientException) - error = error.InnerException; - - var isCancel = error is OperationCanceledException; - if (BeginTransit()) { - m_error = isCancel ? error.InnerException : error; - CompleteTransit(isCancel ? CANCELLED_STATE : REJECTED_STATE); + m_error = error; + CompleteTransit(REJECTED_STATE); Signal(); } else { WaitTransition(); - if (!isCancel || m_state == SUCCEEDED_STATE) + if (m_state == SUCCEEDED_STATE) throw new InvalidOperationException("The promise is already resolved"); } } @@ -140,11 +135,11 @@ case SUCCEEDED_STATE: return; case CANCELLED_STATE: - throw new OperationCanceledException(); + throw new OperationCanceledException("The operation has been cancelled", m_error); case REJECTED_STATE: throw new TargetInvocationException(m_error); default: - throw new ApplicationException(String.Format("Invalid promise state {0}", m_state)); + throw new ApplicationException(String.Format("The promise state {0} is invalid", m_state)); } } #endregion
--- a/Implab/AbstractPromise.cs Mon Apr 18 16:41:17 2016 +0300 +++ b/Implab/AbstractPromise.cs Tue Apr 19 00:50:14 2016 +0300 @@ -134,8 +134,8 @@ } protected void SetResult() { - BeginSetResult(); - EndSetResult(); + if(BeginSetResult()) + EndSetResult(); } } }
--- a/Implab/ActionChainTaskBase.cs Mon Apr 18 16:41:17 2016 +0300 +++ b/Implab/ActionChainTaskBase.cs Tue Apr 19 00:50:14 2016 +0300 @@ -20,34 +20,51 @@ HandleErrorInternal(error); } - - public override void CancelOperation(Exception reason) { if (LockCancelation()) { + if (!(reason is OperationCanceledException)) + reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException(); + if (m_cancel != null) { try { - m_cancel(reason).On(SetResult, SetError, SetCancelled); + m_cancel(reason).On(SetResult, HandleErrorInternal, HandleCancelInternal); } catch (Exception err) { HandleErrorInternal(err); } } else { - SetCancelled(reason); + HandleErrorInternal(reason); } } } - protected void HandleErrorInternal(Exception error) { + void HandleCancelInternal(Exception reason) { + if (!(reason is OperationCanceledException)) + reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException(); + HandleErrorInternal(reason); + } + + void HandleErrorInternal(Exception error) { if (m_error != null) { try { var p = m_error(error); - p.On(SetResult,SetError,SetCancelled); + p.On(SetResult, SetError, SetCancelled); CancellationRequested(p.Cancel); } catch (Exception err) { - SetError(err); + error = err; } } else { + SetErrorInternal(error); + } + } + + void SetErrorInternal(Exception error) { + while (error is PromiseTransientException) + error = error.InnerException; + + if (error is OperationCanceledException) + SetCancelled(error); + else SetError(error); - } } protected bool LockCancelation() {
--- a/Implab/Components/RunnableComponent.cs Mon Apr 18 16:41:17 2016 +0300 +++ b/Implab/Components/RunnableComponent.cs Tue Apr 19 00:50:14 2016 +0300 @@ -139,14 +139,7 @@ throw new PromiseTransientException(e); }, r => { - lock(m_stateMachine) { - if (m_pending == promise) { - Move(Commands.Fail); - m_pending = null; - m_lastError = new OperationCanceledException("The operation has been cancelled", r); - } - - } + // handle cancellation as exception throw new OperationCanceledException("The operation has been cancelled", r); } ); @@ -201,7 +194,7 @@ if (current == null) { stop.Resolve(); } else { - current.On(stop.Resolve, stop.Reject, stop.CancelOperation); + current.On(stop.Resolve, stop.Reject, e => stop.Resolve()); current.Cancel(); } }