Mercurial > pub > ImplabNet
view Implab/ActionChainTaskBase.cs @ 223:27ea7f07e2e4 default
Слияние
author | cin |
---|---|
date | Tue, 22 Aug 2017 09:35:54 +0300 |
parents | b305c678923a |
children |
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) { SetErrorInternal(err); } } else { SetCancelledInternal(reason); } } 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(err); } } else { SetErrorInternal(error); } } } }