diff Implab/FuncChainTaskBase.cs @ 149:eb793fbbe4ea v2

fixed promises cancellation
author cin
date Wed, 06 May 2015 17:11:27 +0300
parents 706fccb85524
children dd4a3590f9c6
line wrap: on
line diff
--- a/Implab/FuncChainTaskBase.cs	Wed Apr 15 07:30:20 2015 +0300
+++ b/Implab/FuncChainTaskBase.cs	Wed May 06 17:11:27 2015 +0300
@@ -8,9 +8,11 @@
 
         int m_cancelationLock;
 
-        protected FuncChainTaskBase( Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel) {
+        protected FuncChainTaskBase( Func<Exception, IPromise<TResult>> error, Func<Exception, IPromise<TResult>> cancel, bool autoCancellable) {
             m_error = error;
             m_cancel = cancel;
+            if (autoCancellable)
+                CancellationRequested(CancelOperation);
         }
 
         public void Reject(Exception error) {
@@ -19,11 +21,15 @@
         }
 
         public override void CancelOperation(Exception reason) {
-            if (m_cancel != null && LockCancelation()) {
-                try {
-                    Observe(m_cancel(reason));
-                } catch(Exception err) {
-                    HandleErrorInternal(err);
+            if (LockCancelation()) {
+                if (m_cancel != null) {
+                    try {
+                        m_cancel(reason).On(SetResult, HandleErrorInternal, SetCancelled);
+                    } catch (Exception err) {
+                        HandleErrorInternal(err);
+                    }
+                } else {
+                    SetCancelled(reason);
                 }
             }
 
@@ -32,7 +38,10 @@
         protected void HandleErrorInternal(Exception error) {
             if (m_error != null) {
                 try {
-                    Observe(m_error(error));
+                    var operation = m_error(error);
+
+                    operation.On(SetResult, SetError, SetCancelled);
+                    CancellationRequested(operation.Cancel);
                 } catch(Exception err) {
                     SetError(err);
                 }
@@ -41,17 +50,6 @@
             }
         }
 
-        protected void Observe(IPromise<TResult> operation) {
-            if (operation == null)
-                throw new NullReferenceException("The task returned null promise");
-
-            // pass operation results to the current promise
-            operation.On(SetResult, SetError, SetCancelled);
-
-            // pass the cancelation request
-            CancellationRequested(operation.Cancel);
-        }
-
         protected bool LockCancelation() {
             return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
         }