diff --git a/Implab/AbstractTask.cs b/Implab/AbstractTask.cs
new file mode 100644
--- /dev/null
+++ b/Implab/AbstractTask.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Threading;
+
+namespace Implab {
+    /// 
+    /// Базовый класс для реализации задачь. Задача представляет собой некторое
+    /// действие, которое можно иницировать и обработать результат его выполнения
+    ///  в виде обещания, для этого оно реализует интерфейс .
+    /// 
+    /// 
+    /// Данный класс определяет стандартное поведение при обработки результатов, в частности
+    /// обработку  и 
+    /// 
+    public abstract class AbstractTask : AbstractPromise {
+        int m_cancelationLock;
+
+        /// 
+        /// Получает эксклюзивное право отмены задания, используется для отмены задания до начала его выполнения.
+        /// 
+        /// true, if cancelation was locked, false otherwise.
+        protected bool LockCancelation() {
+            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
+        }
+
+
+
+        protected void SetErrorInternal(Exception error) {
+            // unwrap 
+            while (error is PromiseTransientException && error.InnerException != null)
+                error = error.InnerException;
+            
+            if (error is OperationCanceledException)
+                SetCancelled(error);
+            else
+                SetError(error);
+        }
+
+        protected void SetCancelledInternal(Exception reason) {
+            SetCancelled(
+                reason == null ? new OperationCanceledException() : reason is OperationCanceledException ? reason : new OperationCanceledException(null, reason)
+            );
+        }
+    }
+}
+
diff --git a/Implab/AbstractTaskT.cs b/Implab/AbstractTaskT.cs
new file mode 100644
--- /dev/null
+++ b/Implab/AbstractTaskT.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading;
+
+namespace Implab {
+    public abstract class AbstractTask : AbstractPromise {
+        int m_cancelationLock;
+
+        /// 
+        /// Получает эксклюзивное право отмены задания, используется для отмены задания до начала его выполнения.
+        /// 
+        /// true, if cancelation was locked, false otherwise.
+        protected bool LockCancelation() {
+            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
+        }
+
+
+
+        protected void SetErrorInternal(Exception error) {
+            // unwrap 
+            while (error is PromiseTransientException && error.InnerException != null)
+                error = error.InnerException;
+
+            if (error is OperationCanceledException)
+                SetCancelled(error);
+            else
+                SetError(error);
+        }
+
+        protected void SetCancelledInternal(Exception reason) {
+            SetCancelled(
+                reason == null ? new OperationCanceledException() : reason is OperationCanceledException ? reason : new OperationCanceledException(null, reason)
+            );
+        }
+    }
+}
+
diff --git a/Implab/ActionChainTask.cs b/Implab/ActionChainTask.cs
--- a/Implab/ActionChainTask.cs
+++ b/Implab/ActionChainTask.cs
@@ -21,8 +21,10 @@ namespace Implab {
             if (m_task != null && LockCancelation()) {
                 try {
                     var p = m_task();
-                    p.On(SetResult, HandleErrorInternal, SetCancelled);
+                    p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
                     CancellationRequested(p.Cancel);
+                } catch (OperationCanceledException reason){
+                    HandleCancelInternal(reason);
                 } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/ActionChainTaskBase.cs b/Implab/ActionChainTaskBase.cs
--- a/Implab/ActionChainTaskBase.cs
+++ b/Implab/ActionChainTaskBase.cs
@@ -2,12 +2,10 @@
 using System.Threading;
 
 namespace Implab {
-    public class ActionChainTaskBase : AbstractPromise {
+    public class ActionChainTaskBase : AbstractTask {
         readonly Func m_error;
         readonly Func m_cancel;
 
-        int m_cancelationLock;
-
         protected ActionChainTaskBase(Func error, Func cancel, bool autoCancellable) {
             m_error = error;
             m_cancel = cancel;
@@ -21,55 +19,44 @@ namespace Implab {
         }
 
         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, HandleErrorInternal, HandleCancelInternal);
-                    } catch (Exception err) {
-                        HandleErrorInternal(err);
-                    }
-                } else {
-                    HandleErrorInternal(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());
             }
         }
 
-        void HandleCancelInternal(Exception reason) {
-            if (!(reason is OperationCanceledException))
-                reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException();
-            HandleErrorInternal(reason);
-        }
-
-        void HandleErrorInternal(Exception error) {
+        protected void HandleErrorInternal(Exception error) {
             if (m_error != null) {
                 try {
                     var p = m_error(error);
-                    p.On(SetResult, SetError, SetCancelled);
+                    p.On(SetResult, SetErrorInternal, SetCancelledInternal);
                     CancellationRequested(p.Cancel);
                 } catch (Exception err) {
-                    error = err;
+                    SetErrorInternal(error);
                 }
             } 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() {
-            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
-        }
     }
 }
 
diff --git a/Implab/ActionChainTaskT.cs b/Implab/ActionChainTaskT.cs
--- a/Implab/ActionChainTaskT.cs
+++ b/Implab/ActionChainTaskT.cs
@@ -12,8 +12,10 @@ namespace Implab {
             if (m_task != null && LockCancelation()) {
                 try {
                     var p = m_task(value);
-                    p.On(SetResult, HandleErrorInternal, SetCancelled);
+                    p.On(SetResult, HandleErrorInternal, HandleCancelInternal);
                     CancellationRequested(p.Cancel);
+                } catch (OperationCanceledException reason) {
+                    HandleCancelInternal(reason);
                 } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/ActionTask.cs b/Implab/ActionTask.cs
--- a/Implab/ActionTask.cs
+++ b/Implab/ActionTask.cs
@@ -12,6 +12,8 @@ namespace Implab {
                 try {
                     m_task();
                     SetResult();
+                } catch(OperationCanceledException reason) {
+                    HandleCancelInternal(reason);
                 } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/ActionTaskBase.cs b/Implab/ActionTaskBase.cs
--- a/Implab/ActionTaskBase.cs
+++ b/Implab/ActionTaskBase.cs
@@ -1,13 +1,10 @@
 using System;
-using System.Threading;
 
 namespace Implab {
-    public class ActionTaskBase : AbstractPromise {
+    public class ActionTaskBase : AbstractTask {
         readonly Action m_cancel;
         readonly Action m_error;
 
-        int m_cancelationLock;
-
         protected ActionTaskBase( Action error, Action cancel, bool autoCancellable) {
             m_error = error;
             m_cancel = cancel;
@@ -21,37 +18,36 @@ namespace Implab {
                 HandleErrorInternal(error);
         }
 
+        public override void CancelOperation(Exception reason) {
+            if (LockCancelation())
+                HandleCancelInternal(reason);
+        }
+
         protected void HandleErrorInternal(Exception error) {
             if (m_error != null) {
                 try {
                     m_error(error);
                     SetResult();
                 } catch(Exception err) {
-                    SetError(err);
+                    SetErrorInternal(err);
                 }
             } else {
-                SetError(error);
+                SetErrorInternal(error);
             }
         }
 
-        public override void CancelOperation(Exception reason) {
-            if (LockCancelation()) {
-                if (m_cancel != null) {
-                    try {
-                        m_cancel(reason);
-                        SetResult();
-                    } catch (Exception err) {
-                        HandleErrorInternal(err);
-                    }
-                } else {
-                    SetCancelled(reason);
+        protected void HandleCancelInternal(Exception error) {
+            if (m_cancel != null) {
+                try {
+                    m_cancel(error);
+                    SetResult();
+                } catch(Exception err) {
+                    HandleErrorInternal(err);
                 }
+            } else {
+                HandleErrorInternal(error ?? new OperationCanceledException());
             }
         }
-
-        protected bool LockCancelation() {
-            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
-        }
     }
 }
 
diff --git a/Implab/ActionTaskT.cs b/Implab/ActionTaskT.cs
--- a/Implab/ActionTaskT.cs
+++ b/Implab/ActionTaskT.cs
@@ -12,6 +12,8 @@ namespace Implab {
                 try {
                     m_task(value);
                     SetResult();
+                } catch(OperationCanceledException reason) {
+                    HandleCancelInternal(reason);
                 } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/Components/RunnableComponent.cs b/Implab/Components/RunnableComponent.cs
--- a/Implab/Components/RunnableComponent.cs
+++ b/Implab/Components/RunnableComponent.cs
@@ -137,10 +137,6 @@ namespace Implab.Components {
                             }
                         }
                         throw new PromiseTransientException(e);
-                    },
-                    r => {
-                        // handle cancellation as exception
-                        throw new OperationCanceledException("The operation has been cancelled", r);
                     }
                 );
 
@@ -194,7 +190,13 @@ namespace Implab.Components {
             if (current == null) {
                 stop.Resolve();
             } else {
-                current.On(stop.Resolve, stop.Reject, e => stop.Resolve());
+                // связваем текущую операцию с операцией остановки
+                current.On(
+                    stop.Resolve, // если текущая операция заверщилась, то можно начинать остановку
+                    stop.Reject, // если текущая операция дала ошибку - то все плохо, нельзя продолжать
+                    e => stop.Resolve() // если текущая отменилась, то можно начинать остановку
+                );
+                // посылаем текущей операции сигнал остановки
                 current.Cancel();
             }
         }
diff --git a/Implab/FuncChainTask.cs b/Implab/FuncChainTask.cs
--- a/Implab/FuncChainTask.cs
+++ b/Implab/FuncChainTask.cs
@@ -13,8 +13,10 @@ namespace Implab {
             if (m_task != null && LockCancelation()) {
                 try {
                     var operation = m_task();
-                    operation.On(SetResult, HandleErrorInternal, SetCancelled);
+                    operation.On(SetResult, HandleErrorInternal, HandleCancelInternal);
                     CancellationRequested(operation.Cancel);
+                } catch (OperationCanceledException reason) {
+                    HandleCancelInternal(reason);
                 } catch (Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/FuncChainTaskBase.cs b/Implab/FuncChainTaskBase.cs
--- a/Implab/FuncChainTaskBase.cs
+++ b/Implab/FuncChainTaskBase.cs
@@ -1,13 +1,10 @@
 using System;
-using System.Threading;
 
 namespace Implab {
-    public class FuncChainTaskBase : AbstractPromise {
+    public class FuncChainTaskBase : AbstractTask {
         readonly Func> m_error;
         readonly Func> m_cancel;
 
-        int m_cancelationLock;
-
         protected FuncChainTaskBase( Func> error, Func> cancel, bool autoCancellable) {
             m_error = error;
             m_cancel = cancel;
@@ -21,37 +18,36 @@ namespace Implab {
         }
 
         public override void CancelOperation(Exception reason) {
-            if (LockCancelation()) {
-                if (m_cancel != null) {
-                    try {
-                        m_cancel(reason).On(SetResult, HandleErrorInternal, SetCancelled);
-                    } catch (Exception err) {
-                        HandleErrorInternal(err);
-                    }
-                } else {
-                    SetCancelled(reason);
-                }
-            }
-
+            if (LockCancelation())
+                HandleCancelInternal(reason);
         }
 
         protected void HandleErrorInternal(Exception error) {
             if (m_error != null) {
                 try {
-                    var operation = m_error(error);
-
-                    operation.On(SetResult, SetError, SetCancelled);
-                    CancellationRequested(operation.Cancel);
+                    var p = m_error(error);
+                    p.On(SetResult, SetErrorInternal, SetCancelledInternal);
+                    CancellationRequested(p.Cancel);
                 } catch(Exception err) {
-                    SetError(err);
+                    SetErrorInternal(err);
                 }
             } else {
-                SetError(error);
+                SetErrorInternal(error);
             }
         }
 
-        protected bool LockCancelation() {
-            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
+        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());
+            }
         }
     }
 }
diff --git a/Implab/FuncChainTaskT.cs b/Implab/FuncChainTaskT.cs
--- a/Implab/FuncChainTaskT.cs
+++ b/Implab/FuncChainTaskT.cs
@@ -14,6 +14,8 @@ namespace Implab {
                     var operation = m_task(value);
                     operation.On(SetResult, HandleErrorInternal, SetCancelled);
                     CancellationRequested(operation.Cancel);
+                } catch (OperationCanceledException reason) {
+                    HandleCancelInternal(reason);
                 } catch (Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/FuncTask.cs b/Implab/FuncTask.cs
--- a/Implab/FuncTask.cs
+++ b/Implab/FuncTask.cs
@@ -13,6 +13,8 @@ namespace Implab {
             if (m_task != null && LockCancelation()) {
                 try {
                     SetResult(m_task());
+                } catch(OperationCanceledException reason)  {
+                    HandleCancelInternal(reason);
                 } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
diff --git a/Implab/FuncTaskBase.cs b/Implab/FuncTaskBase.cs
--- a/Implab/FuncTaskBase.cs
+++ b/Implab/FuncTaskBase.cs
@@ -1,13 +1,10 @@
 using System;
-using System.Threading;
 
 namespace Implab {
-    public class FuncTaskBase : AbstractPromise {
+    public class FuncTaskBase : AbstractTask {
         readonly Func m_cancel;
         readonly Func m_error;
 
-        int m_cancelationLock;
-
         protected FuncTaskBase( Func error, Func cancel, bool autoCancellable) {
             m_error = error;
             m_cancel = cancel;
@@ -26,30 +23,30 @@ namespace Implab {
                 try {
                     SetResult(m_error(error));
                 } catch(Exception err) {
-                    SetError(err);
+                    SetErrorInternal(err);
                 }
             } else {
-                SetError(error);
+                SetErrorInternal(error);
             }
         }
 
         public override void CancelOperation(Exception reason) {
-            if (LockCancelation()) {
-                if (m_cancel != null) {
-                    try {
-                        SetResult(m_cancel(reason));
-                    } catch (Exception err) {
-                        HandleErrorInternal(err);
-                    }
-                } else {
-                    SetCancelled(reason);
+            if (LockCancelation())
+                HandleCancelInternal(reason);
+        }
+
+        protected void HandleCancelInternal(Exception reason) {
+            if (m_cancel != null) {
+                try {
+                    SetResult(m_cancel(reason));
+                } catch (Exception err) {
+                    HandleErrorInternal(err);
                 }
+            } else {
+                HandleErrorInternal(reason ?? new OperationCanceledException());
             }
         }
 
-        protected bool LockCancelation() {
-            return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
-        }
     }
 }
 
diff --git a/Implab/FuncTaskT.cs b/Implab/FuncTaskT.cs
--- a/Implab/FuncTaskT.cs
+++ b/Implab/FuncTaskT.cs
@@ -12,7 +12,9 @@ namespace Implab {
             if (m_task != null && LockCancelation()) {
                 try {
                     SetResult(m_task(value));
-                } catch (Exception err) {
+                } catch(OperationCanceledException reason)  {
+                    HandleCancelInternal(reason);
+                } catch(Exception err) {
                     HandleErrorInternal(err);
                 }
             }
diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj
--- a/Implab/Implab.csproj
+++ b/Implab/Implab.csproj
@@ -193,6 +193,8 @@
     
     
     
+    
+