Mercurial > pub > ImplabNet
view Implab/ActionChainTaskBase.cs @ 189:b60643b47078 ref20160224
Закрыть ветку ref20160224
author | cin |
---|---|
date | Fri, 22 Apr 2016 13:07:41 +0300 |
parents | dd4a3590f9c6 |
children | 40d7fed4a09e |
line wrap: on
line source
using System; using System.Threading; namespace Implab { public class ActionChainTaskBase : AbstractTask { readonly Func<Exception, IPromise> m_error; readonly Func<Exception, IPromise> m_cancel; protected ActionChainTaskBase(Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) { m_error = error; m_cancel = cancel; if (autoCancellable) CancellationRequested(CancelOperation); } public void Reject(Exception error) { if (LockCancelation()) HandleErrorInternal(error); } public override void CancelOperation(Exception reason) { if (LockCancelation()) // отмена вызвана до начала выполнения задачи HandleCancelInternal(reason); } protected void HandleCancelInternal(Exception reason) { if (m_cancel != null) { try { // вызываем обработчик отмены var p = m_cancel(reason); p.On(SetResult, HandleErrorInternal, SetCancelledInternal); // сообщаем асинхронной операции, что клиент уже не хочет получать результат // т.е. если он инициировал отмену, задача отменилась, вызвался обрабочик отмены // отбработчику сообщили, что результат уже не нужен и уже сам обработчик решает // отдавать ли результат или подтвердить отмену (или вернуть ошибку). CancellationRequested(p.Cancel); } catch (Exception err) { HandleErrorInternal(err); } } else { HandleErrorInternal(reason ?? new OperationCanceledException()); } } protected void HandleErrorInternal(Exception error) { if (m_error != null) { try { var p = m_error(error); p.On(SetResult, SetErrorInternal, SetCancelledInternal); CancellationRequested(p.Cancel); } catch (Exception err) { SetErrorInternal(error); } } else { SetErrorInternal(error); } } } }