diff Implab/Promise.cs @ 101:279e226dffdd v2

code cleanup added EnsureDispatched extension
author cin
date Thu, 06 Nov 2014 20:03:19 +0300
parents 8ddf1648eca4
children 5f10d54b45df
line wrap: on
line diff
--- a/Implab/Promise.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/Promise.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -1,17 +1,11 @@
 using System;
 using System.Collections.Generic;
 using System.Reflection;
-using System.Diagnostics;
 using System.Threading;
 using Implab.Parallels;
 
 namespace Implab {
 
-    public delegate void ErrorHandler(Exception e);
-    public delegate T ErrorHandler<out T>(Exception e);
-    public delegate void ResultHandler<in T>(T result);
-    public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result);
-
     /// <summary>
     /// Класс для асинхронного получения результатов. Так называемое "обещание".
     /// </summary>
@@ -49,8 +43,8 @@
     public class Promise<T> : IPromise<T> {
 
         protected struct HandlerDescriptor {
-            public ResultHandler<T> resultHandler;
-            public ErrorHandler<T> errorHandler;
+            public Action<T> resultHandler;
+            public Func<Exception,T> errorHandler;
             public Action cancellHandler;
             public Promise<T> medium;
 
@@ -104,9 +98,7 @@
         const int REJECTED_STATE = 3;
         const int CANCELLED_STATE = 4;
 
-        readonly bool m_cancellable;
-
-        int m_childrenCount = 0;
+        int m_childrenCount;
         int m_state;
         T m_result;
         Exception m_error;
@@ -114,11 +106,9 @@
         readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
 
         public Promise() {
-            m_cancellable = true;
         }
 
-        public Promise(IPromise parent, bool cancellable) {
-            m_cancellable = cancellable;
+        public Promise(IPromise parent) {
             if (parent != null)
                 AddHandler(
                     null,
@@ -218,17 +208,17 @@
         /// </summary>
         /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks>
         public void Cancel() {
-            if (m_cancellable && BeginTransit()) {
+            if (BeginTransit()) {
                 CompleteTransit(CANCELLED_STATE);
                 OnStateChanged();
             }
         }
 
-        public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error, Action cancel) {
+        public IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel) {
             if (success == null && error == null && cancel == null)
                 return this;
 
-            var medium = new Promise<T>(this, true);
+            var medium = new Promise<T>(this);
 
             AddHandler(success, error, cancel, medium);
 
@@ -242,11 +232,11 @@
         /// This handler will recieve an operation result as a parameter.</param>
         /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
         /// <returns>The new promise chained to this one.</returns>
-        public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) {
+        public IPromise<T> Then(Action<T> success, Func<Exception,T> error) {
             if (success == null && error == null)
                 return this;
 
-            var medium = new Promise<T>(this, true);
+            var medium = new Promise<T>(this);
 
             AddHandler(success, error, null, medium);
 
@@ -256,11 +246,11 @@
         
 
 
-        public IPromise<T> Then(ResultHandler<T> success) {
+        public IPromise<T> Then(Action<T> success) {
             if (success == null)
                 return this;
 
-            var medium = new Promise<T>(this, true);
+            var medium = new Promise<T>(this);
 
             AddHandler(success, null, null, medium);
 
@@ -284,11 +274,11 @@
         /// всей цепи обещаний снизу (с самого последнего обещания).
         /// </para>
         /// </remarks>
-        public void Last(ResultHandler<T> success, ErrorHandler error, Action cancel) {
+        public void Last(Action<T> success, Action<Exception> error, Action cancel) {
             if (success == null && error == null && cancel == null)
                 return;
 
-            ErrorHandler<T> errorHandler = null;
+            Func<Exception,T> errorHandler = null;
             if (error != null)
                 errorHandler = err => {
                     error(err);
@@ -297,19 +287,19 @@
             AddHandler(success, errorHandler, cancel, null);
         }
 
-        public void Last(ResultHandler<T> success, ErrorHandler error) {
+        public void Last(Action<T> success, Action<Exception> error) {
             Last(success, error, null);
         }
 
-        public void Last(ResultHandler<T> success) {
+        public void Last(Action<T> success) {
             Last(success, null, null);
         }
 
-        public IPromise Error(ErrorHandler error) {
+        public IPromise Error(Action<Exception> error) {
             if (error == null)
                 return this;
 
-            var medium = new Promise<T>(this, true);
+            var medium = new Promise<T>(this);
 
             AddHandler(
                 null,
@@ -332,11 +322,11 @@
         /// </remarks>
         /// <param name="handler">The error handler which returns the result of the promise.</param>
         /// <returns>New promise.</returns>
-        public IPromise<T> Error(ErrorHandler<T> handler) {
+        public IPromise<T> Error(Func<Exception,T> handler) {
             if (handler == null)
                 return this;
 
-            var medium = new Promise<T>(this, true);
+            var medium = new Promise<T>(this);
 
             AddHandler(null, handler, null, medium);
 
@@ -352,14 +342,14 @@
         /// исключение возникшее при выполнении операции.</param>
         /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns>
         /// <param name = "cancel"></param>
-        public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error, Action cancel) {
+        public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error, Action cancel) {
             Safe.ArgumentNotNull(mapper, "mapper");
             
             // создаем прицепленное обещание
-            var medium = new Promise<TNew>(this, true);
+            var medium = new Promise<TNew>(this);
 
-            ResultHandler<T> resultHandler = result => medium.Resolve(mapper(result));
-            ErrorHandler<T> errorHandler;
+            Action<T> resultHandler = result => medium.Resolve(mapper(result));
+            Func<Exception,T> errorHandler;
             if (error != null)
                 errorHandler = e => {
                     try {
@@ -396,11 +386,11 @@
             return medium;
         }
 
-        public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error) {
+        public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error) {
             return Then(mapper, error, null);
         }
 
-        public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper) {
+        public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper) {
             return Then(mapper, null, null);
         }
 
@@ -415,7 +405,7 @@
         /// исключение возникшее при выполнении текуещй операции.</param>
         /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns>
         /// <param name = "cancel"></param>
-        public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error, Action cancel) {
+        public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error, Action cancel) {
 
             Safe.ArgumentNotNull(chained, "chained");
 
@@ -423,9 +413,9 @@
             // создать посредника, к которому будут подвызяваться следующие обработчики.
             // когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы
             // передать через него результаты работы.
-            var medium = new Promise<TNew>(this, true);
+            var medium = new Promise<TNew>(this);
 
-            ResultHandler<T> resultHandler = delegate(T result) {
+            Action<T> resultHandler = delegate(T result) {
                 if (medium.IsCancelled)
                     return;
 
@@ -440,13 +430,17 @@
                 // notify chained operation that it's not needed anymore
                 // порядок вызова Then, Cancelled важен, поскольку от этого
                 // зависит IsExclusive
-                medium.Cancelled(() => {
-                    if (promise.IsExclusive)
-                        promise.Cancel();
-                });
+                medium.Last(
+                    null,
+                    null,
+                    () => {
+                        if (promise.IsExclusive)
+                            promise.Cancel();
+                    }
+                );
             };
 
-            ErrorHandler<T> errorHandler;
+            Func<Exception,T> errorHandler;
 
             if (error != null)
                 errorHandler = delegate(Exception e) {
@@ -498,16 +492,16 @@
             return medium;
         }
 
-        public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error) {
+        public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error) {
             return Chain(chained, error, null);
         }
 
-        public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained) {
+        public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained) {
             return Chain(chained, null, null);
         }
 
         public IPromise<T> Cancelled(Action handler) {
-            var medium = new Promise<T>(this,true);
+            var medium = new Promise<T>(this);
             AddHandler(null, null, handler, medium);
             return medium;
         }
@@ -585,7 +579,7 @@
             return Join(Timeout.Infinite);
         }
 
-        void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) {
+        void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium) {
             if (success != null || error != null)
                 Interlocked.Increment(ref m_childrenCount);
 
@@ -759,10 +753,10 @@
 
         #region IPromiseBase explicit implementation
 
-        IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) {
+        IPromise IPromise.Then(Action success, Action<Exception> error, Action cancel) {
             return Then(
-                success != null ? new ResultHandler<T>(x => success()) : null,
-                error != null ? new ErrorHandler<T>(e => {
+                success != null ? new Action<T>(x => success()) : null,
+                error != null ? new Func<Exception,T>(e => {
                     error(e);
                     return default(T);
                 }) : null,
@@ -770,10 +764,10 @@
             );
         }
 
-        IPromise IPromise.Then(Action success, ErrorHandler error) {
+        IPromise IPromise.Then(Action success, Action<Exception> error) {
             return Then(
-                success != null ? new ResultHandler<T>(x => success()) : null,
-                error != null ? new ErrorHandler<T>(e => {
+                success != null ? new Action<T>(x => success()) : null,
+                error != null ? new Func<Exception,T>(e => {
                     error(e);
                     return default(T);
                 }) : null
@@ -785,16 +779,16 @@
             return Then(x => success());
         }
 
-        IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) {
+        IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
             return ChainNoResult(chained, error, cancel);
         }
 
-        IPromise ChainNoResult(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) {
+        IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
                 Safe.ArgumentNotNull(chained, "chained");
 
-            var medium = new Promise<object>(this, true);
+            var medium = new Promise<object>(this);
 
-                ResultHandler<T> resultHandler = delegate(T result) {
+            Action<T> resultHandler = delegate {
                     if (medium.IsCancelled)
                         return;
 
@@ -815,7 +809,7 @@
                     });
                 };
 
-                ErrorHandler<T> errorHandler;
+            Func<Exception,T> errorHandler;
 
                 if (error != null)
                     errorHandler = delegate(Exception e) {
@@ -866,7 +860,7 @@
 
                 return medium;
         }
-        IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error) {
+        IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) {
             return ChainNoResult(chained, error, null);
         }
         IPromise IPromise.Chain(Func<IPromise> chained) {
@@ -874,11 +868,11 @@
         }            
 
 
-        void IPromise.Last(Action success, ErrorHandler error, Action cancel) {
+        void IPromise.Last(Action success, Action<Exception> error, Action cancel) {
             Last(x => success(), error, cancel);
         }
 
-        void IPromise.Last(Action success, ErrorHandler error) {
+        void IPromise.Last(Action success, Action<Exception> error) {
             Last(x => success(), error, null);
         }
 
@@ -886,7 +880,7 @@
             Last(x => success(), null, null);
         }
 
-        IPromise IPromise.Error(ErrorHandler error) {
+        IPromise IPromise.Error(Action<Exception> error) {
             return Error(error);
         }