using System; using System.Threading; namespace Implab { public class ChainTask : AbstractPromise, IDeferred { readonly Func m_task; readonly Action m_error; readonly Action m_cancel; int m_cancelationLock; public ChainTask(Func task, Func error, Func cancel) { m_task = task; } public void Resolve() { if (m_task != null && LockCancelation()) { try { var operation = m_task(); if (operation == null) throw new NullReferenceException("The task returned null promise"); operation.On(SetResult, SetError, SetCancelled); CancelationRequested(operation.Cancel); } catch(Exception err) { HandleErrorInternal(err); } } } public void Reject(Exception error) { throw new NotImplementedException(); } protected void HandleErrorInternal(Exception error) { if (m_error != null) { try { m_error(error); SetResult(); } catch(Exception err) { SetError(err); } } else { SetError(error); } } protected bool LockCancelation() { return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0); } } }