changeset 101:279e226dffdd v2

code cleanup added EnsureDispatched extension
author cin
date Thu, 06 Nov 2014 20:03:19 +0300
parents 673947ce458a
children b4c4d65b7def
files Implab/IPromise.cs Implab/IPromiseT.cs Implab/Parallels/ArrayTraits.cs Implab/Promise.cs Implab/PromiseExtensions.cs Implab/SyncContextPromise.cs
diffstat 6 files changed, 103 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/IPromise.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/IPromise.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -27,12 +27,12 @@
         /// </summary>
         bool IsCancelled { get; }
 
-        IPromise Then(Action success, ErrorHandler error, Action cancel);
-        IPromise Then(Action success, ErrorHandler error);
+        IPromise Then(Action success, Action<Exception> error, Action cancel);
+        IPromise Then(Action success, Action<Exception> error);
         IPromise Then(Action success);
 
-        IPromise Chain(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel);
-        IPromise Chain(Func<IPromise> chained, ErrorHandler<IPromise> error);
+        IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Action cancel);
+        IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error);
         IPromise Chain(Func<IPromise> chained);
 
         /// <summary>
@@ -41,13 +41,13 @@
         /// <param name="success">Success.</param>
         /// <param name="error">Error.</param>
         /// <param name="cancel">Cancel.</param>
-        void Last(Action success, ErrorHandler error, Action cancel);
-        void Last(Action success, ErrorHandler error);
+        void Last(Action success, Action<Exception> error, Action cancel);
+        void Last(Action success, Action<Exception> error);
         void Last(Action success);
 
-        IPromise Error(ErrorHandler error);
+        IPromise Error(Action<Exception> error);
         /// <summary>
-        /// Обрабатывает либо ошибку, либо результат. Событие отмены не обрабатывается.
+        /// Обрабатывает либо ошибку, либо результат, либо отмену.
         /// </summary>
         /// <param name="handler">Обработчик.</param>
         /// <remarks>После обработке ошибки, она передается дальше.</remarks>
@@ -58,9 +58,9 @@
         /// <remarks>После обработке ошибки, она передается дальше.</remarks>
         IPromise Anyway(Action handler);
         /// <summary>
-        /// Обработчик для регистрации отмены обещания, событие отмены не может быть подавлено.
+        /// Обработчик для регистрации отмены обещания.
         /// </summary>
-        /// <returns>Новое обещание, связанное с текущим.</returns>
+        /// <returns>Новое обещание, связанное с текущим, выполнится после указанного обработчика.</returns>
         /// <param name="handler">Обработчик события.</param>
         /// <remarks>Если обработчик вызывает исключение, то оно передается обработчику ошибки, результат работы
         /// которого будет передан связанному обещанию</remarks>
--- a/Implab/IPromiseT.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/IPromiseT.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -7,31 +7,31 @@
 
         new T Join(int timeout);
 
-        void Last(ResultHandler<T> success, ErrorHandler error, Action cancel);
+        void Last(Action<T> success, Action<Exception> error, Action cancel);
         
-        void Last(ResultHandler<T> success, ErrorHandler error);
+        void Last(Action<T> success, Action<Exception> error);
 
-        void Last(ResultHandler<T> success);
+        void Last(Action<T> success);
 
-        IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error, Action cancel);
+        IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel);
 
-        IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
+        IPromise<T> Then(Action<T> success, Func<Exception,T> error);
 
-        IPromise<T> Then(ResultHandler<T> success);
+        IPromise<T> Then(Action<T> success);
 
-        IPromise<T2> Then<T2>(ResultMapper<T, T2> mapper, ErrorHandler<T2> error, Action cancel);
+        IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error, Action cancel);
 
-        IPromise<T2> Then<T2>(ResultMapper<T, T2> mapper, ErrorHandler<T2> error);
+        IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception,T2> error);
 
-        IPromise<T2> Then<T2>(ResultMapper<T, T2> mapper);
+        IPromise<T2> Then<T2>(Func<T, T2> mapper);
 
-        IPromise<T2> Chain<T2>(ResultMapper<T, IPromise<T2>> chained, ErrorHandler<IPromise<T2>> error, Action cancel);
+        IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error, Action cancel);
 
-        IPromise<T2> Chain<T2>(ResultMapper<T, IPromise<T2>> chained, ErrorHandler<IPromise<T2>> error);
+        IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception,IPromise<T2>> error);
 
-        IPromise<T2> Chain<T2>(ResultMapper<T, IPromise<T2>> chained);
+        IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained);
 
-        IPromise<T> Error(ErrorHandler<T> error);
+        IPromise<T> Error(Func<Exception,T> error);
 
         new IPromise<T> Cancelled(Action handler);
 
--- a/Implab/Parallels/ArrayTraits.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/Parallels/ArrayTraits.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -1,9 +1,6 @@
 using Implab.Diagnostics;
 using System;
-using System.Collections.Generic;
 using System.Diagnostics;
-using System.Linq;
-using System.Text;
 using System.Threading;
 
 namespace Implab.Parallels {
@@ -146,13 +143,13 @@
             return iter.Promise;
         }
 
-        public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, ResultMapper<TSrc, IPromise<TDst>> transform, int threads) {
+        public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, Func<TSrc, IPromise<TDst>> transform, int threads) {
             if (source == null)
                 throw new ArgumentNullException("source");
             if (transform == null)
                 throw new ArgumentNullException("transform");
             if (threads <= 0)
-                throw new ArgumentOutOfRangeException("Threads number must be greater then zero");
+                throw new ArgumentOutOfRangeException("threads","Threads number must be greater then zero");
 
             if (source.Length == 0)
                 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
--- 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);
         }
 
--- a/Implab/PromiseExtensions.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/PromiseExtensions.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -12,7 +12,7 @@
             if (context == null)
                 return that;
 
-            var p = new SyncContextPromise<T>(context, that, true);
+            var p = new SyncContextPromise<T>(context, that);
 
             that.Last(
                 p.Resolve,
@@ -26,7 +26,7 @@
             Safe.ArgumentNotNull(that, "that");
             Safe.ArgumentNotNull(context, "context");
 
-            var p = new SyncContextPromise<T>(context, that, true);
+            var p = new SyncContextPromise<T>(context, that);
 
             that.Last(
                 p.Resolve,
@@ -36,6 +36,24 @@
             return p;
         }
 
+        /// <summary>
+        /// Ensures the dispatched.
+        /// </summary>
+        /// <returns>The dispatched.</returns>
+        /// <param name="that">That.</param>
+        /// <param name="head">Head.</param>
+        /// <param name="cleanup">Cleanup.</param>
+        /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
+        /// <typeparam name="T">The 2nd type parameter.</typeparam>
+        public static TPromise EnsureDispatched<TPromise,T>(this TPromise that, IPromise<T> head, Action<T> cleanup) where TPromise : IPromise{
+            Safe.ArgumentNotNull(that, "that");
+            Safe.ArgumentNotNull(head, "head");
+
+            that.Last(null,null,() => head.Last(cleanup));
+
+            return that;
+        }
+
         public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult,T> callback) {
             Safe.ArgumentNotNull(that, "that");
             Safe.ArgumentNotNull(callback, "callback");
--- a/Implab/SyncContextPromise.cs	Wed Nov 05 16:39:56 2014 +0300
+++ b/Implab/SyncContextPromise.cs	Thu Nov 06 20:03:19 2014 +0300
@@ -9,8 +9,8 @@
             m_context = context;
         }
 
-        public SyncContextPromise(SynchronizationContext context, IPromise parent, bool cancellable)
-            : base(parent, cancellable) {
+        public SyncContextPromise(SynchronizationContext context, IPromise parent)
+            : base(parent) {
             Safe.ArgumentNotNull(context, "context");
             m_context = context;
         }