# HG changeset patch # User cin # Date 2014-11-06 17:03:19 # Node ID 279e226dffdd693ceeb710d39ac38a68b0931e3e # Parent 673947ce458a94e072967b0525301540a7a73a56 code cleanup added EnsureDispatched extension diff --git a/Implab/IPromise.cs b/Implab/IPromise.cs --- a/Implab/IPromise.cs +++ b/Implab/IPromise.cs @@ -27,12 +27,12 @@ namespace Implab { /// bool IsCancelled { get; } - IPromise Then(Action success, ErrorHandler error, Action cancel); - IPromise Then(Action success, ErrorHandler error); + IPromise Then(Action success, Action error, Action cancel); + IPromise Then(Action success, Action error); IPromise Then(Action success); - IPromise Chain(Func chained, ErrorHandler error, Action cancel); - IPromise Chain(Func chained, ErrorHandler error); + IPromise Chain(Func chained, Func error, Action cancel); + IPromise Chain(Func chained, Func error); IPromise Chain(Func chained); /// @@ -41,13 +41,13 @@ namespace Implab { /// Success. /// Error. /// Cancel. - void Last(Action success, ErrorHandler error, Action cancel); - void Last(Action success, ErrorHandler error); + void Last(Action success, Action error, Action cancel); + void Last(Action success, Action error); void Last(Action success); - IPromise Error(ErrorHandler error); + IPromise Error(Action error); /// - /// Обрабатывает либо ошибку, либо результат. Событие отмены не обрабатывается. + /// Обрабатывает либо ошибку, либо результат, либо отмену. /// /// Обработчик. /// После обработке ошибки, она передается дальше. @@ -58,9 +58,9 @@ namespace Implab { /// После обработке ошибки, она передается дальше. IPromise Anyway(Action handler); /// - /// Обработчик для регистрации отмены обещания, событие отмены не может быть подавлено. + /// Обработчик для регистрации отмены обещания. /// - /// Новое обещание, связанное с текущим. + /// Новое обещание, связанное с текущим, выполнится после указанного обработчика. /// Обработчик события. /// Если обработчик вызывает исключение, то оно передается обработчику ошибки, результат работы /// которого будет передан связанному обещанию diff --git a/Implab/IPromiseT.cs b/Implab/IPromiseT.cs --- a/Implab/IPromiseT.cs +++ b/Implab/IPromiseT.cs @@ -7,31 +7,31 @@ namespace Implab { new T Join(int timeout); - void Last(ResultHandler success, ErrorHandler error, Action cancel); + void Last(Action success, Action error, Action cancel); - void Last(ResultHandler success, ErrorHandler error); + void Last(Action success, Action error); - void Last(ResultHandler success); + void Last(Action success); - IPromise Then(ResultHandler success, ErrorHandler error, Action cancel); + IPromise Then(Action success, Func error, Action cancel); - IPromise Then(ResultHandler success, ErrorHandler error); + IPromise Then(Action success, Func error); - IPromise Then(ResultHandler success); + IPromise Then(Action success); - IPromise Then(ResultMapper mapper, ErrorHandler error, Action cancel); + IPromise Then(Func mapper, Func error, Action cancel); - IPromise Then(ResultMapper mapper, ErrorHandler error); + IPromise Then(Func mapper, Func error); - IPromise Then(ResultMapper mapper); + IPromise Then(Func mapper); - IPromise Chain(ResultMapper> chained, ErrorHandler> error, Action cancel); + IPromise Chain(Func> chained, Func> error, Action cancel); - IPromise Chain(ResultMapper> chained, ErrorHandler> error); + IPromise Chain(Func> chained, Func> error); - IPromise Chain(ResultMapper> chained); + IPromise Chain(Func> chained); - IPromise Error(ErrorHandler error); + IPromise Error(Func error); new IPromise Cancelled(Action handler); diff --git a/Implab/Parallels/ArrayTraits.cs b/Implab/Parallels/ArrayTraits.cs --- a/Implab/Parallels/ArrayTraits.cs +++ b/Implab/Parallels/ArrayTraits.cs @@ -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 @@ namespace Implab.Parallels { return iter.Promise; } - public static IPromise ChainedMap(this TSrc[] source, ResultMapper> transform, int threads) { + public static IPromise ChainedMap(this TSrc[] source, Func> 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.ResultToPromise(new TDst[0]); diff --git a/Implab/Promise.cs b/Implab/Promise.cs --- a/Implab/Promise.cs +++ b/Implab/Promise.cs @@ -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(Exception e); - public delegate void ResultHandler(T result); - public delegate TNew ResultMapper(TSrc result); - /// /// Класс для асинхронного получения результатов. Так называемое "обещание". /// @@ -49,8 +43,8 @@ namespace Implab { public class Promise : IPromise { protected struct HandlerDescriptor { - public ResultHandler resultHandler; - public ErrorHandler errorHandler; + public Action resultHandler; + public Func errorHandler; public Action cancellHandler; public Promise medium; @@ -104,9 +98,7 @@ namespace Implab { 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 @@ namespace Implab { readonly MTQueue m_handlers = new MTQueue(); 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 @@ namespace Implab { /// /// Для определения была ли операция отменена следует использовать свойство . public void Cancel() { - if (m_cancellable && BeginTransit()) { + if (BeginTransit()) { CompleteTransit(CANCELLED_STATE); OnStateChanged(); } } - public IPromise Then(ResultHandler success, ErrorHandler error, Action cancel) { + public IPromise Then(Action success, Func error, Action cancel) { if (success == null && error == null && cancel == null) return this; - var medium = new Promise(this, true); + var medium = new Promise(this); AddHandler(success, error, cancel, medium); @@ -242,11 +232,11 @@ namespace Implab { /// This handler will recieve an operation result as a parameter. /// Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation. /// The new promise chained to this one. - public IPromise Then(ResultHandler success, ErrorHandler error) { + public IPromise Then(Action success, Func error) { if (success == null && error == null) return this; - var medium = new Promise(this, true); + var medium = new Promise(this); AddHandler(success, error, null, medium); @@ -256,11 +246,11 @@ namespace Implab { - public IPromise Then(ResultHandler success) { + public IPromise Then(Action success) { if (success == null) return this; - var medium = new Promise(this, true); + var medium = new Promise(this); AddHandler(success, null, null, medium); @@ -284,11 +274,11 @@ namespace Implab { /// всей цепи обещаний снизу (с самого последнего обещания). /// /// - public void Last(ResultHandler success, ErrorHandler error, Action cancel) { + public void Last(Action success, Action error, Action cancel) { if (success == null && error == null && cancel == null) return; - ErrorHandler errorHandler = null; + Func errorHandler = null; if (error != null) errorHandler = err => { error(err); @@ -297,19 +287,19 @@ namespace Implab { AddHandler(success, errorHandler, cancel, null); } - public void Last(ResultHandler success, ErrorHandler error) { + public void Last(Action success, Action error) { Last(success, error, null); } - public void Last(ResultHandler success) { + public void Last(Action success) { Last(success, null, null); } - public IPromise Error(ErrorHandler error) { + public IPromise Error(Action error) { if (error == null) return this; - var medium = new Promise(this, true); + var medium = new Promise(this); AddHandler( null, @@ -332,11 +322,11 @@ namespace Implab { /// /// The error handler which returns the result of the promise. /// New promise. - public IPromise Error(ErrorHandler handler) { + public IPromise Error(Func handler) { if (handler == null) return this; - var medium = new Promise(this, true); + var medium = new Promise(this); AddHandler(null, handler, null, medium); @@ -352,14 +342,14 @@ namespace Implab { /// исключение возникшее при выполнении операции. /// Новое обещание, которое будет выполнено при выполнении исходного обещания. /// - public IPromise Then(ResultMapper mapper, ErrorHandler error, Action cancel) { + public IPromise Then(Func mapper, Func error, Action cancel) { Safe.ArgumentNotNull(mapper, "mapper"); // создаем прицепленное обещание - var medium = new Promise(this, true); + var medium = new Promise(this); - ResultHandler resultHandler = result => medium.Resolve(mapper(result)); - ErrorHandler errorHandler; + Action resultHandler = result => medium.Resolve(mapper(result)); + Func errorHandler; if (error != null) errorHandler = e => { try { @@ -396,11 +386,11 @@ namespace Implab { return medium; } - public IPromise Then(ResultMapper mapper, ErrorHandler error) { + public IPromise Then(Func mapper, Func error) { return Then(mapper, error, null); } - public IPromise Then(ResultMapper mapper) { + public IPromise Then(Func mapper) { return Then(mapper, null, null); } @@ -415,7 +405,7 @@ namespace Implab { /// исключение возникшее при выполнении текуещй операции. /// Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции. /// - public IPromise Chain(ResultMapper> chained, ErrorHandler> error, Action cancel) { + public IPromise Chain(Func> chained, Func> error, Action cancel) { Safe.ArgumentNotNull(chained, "chained"); @@ -423,9 +413,9 @@ namespace Implab { // создать посредника, к которому будут подвызяваться следующие обработчики. // когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы // передать через него результаты работы. - var medium = new Promise(this, true); + var medium = new Promise(this); - ResultHandler resultHandler = delegate(T result) { + Action resultHandler = delegate(T result) { if (medium.IsCancelled) return; @@ -440,13 +430,17 @@ namespace Implab { // 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 errorHandler; + Func errorHandler; if (error != null) errorHandler = delegate(Exception e) { @@ -498,16 +492,16 @@ namespace Implab { return medium; } - public IPromise Chain(ResultMapper> chained, ErrorHandler> error) { + public IPromise Chain(Func> chained, Func> error) { return Chain(chained, error, null); } - public IPromise Chain(ResultMapper> chained) { + public IPromise Chain(Func> chained) { return Chain(chained, null, null); } public IPromise Cancelled(Action handler) { - var medium = new Promise(this,true); + var medium = new Promise(this); AddHandler(null, null, handler, medium); return medium; } @@ -585,7 +579,7 @@ namespace Implab { return Join(Timeout.Infinite); } - void AddHandler(ResultHandler success, ErrorHandler error, Action cancel, Promise medium) { + void AddHandler(Action success, Func error, Action cancel, Promise medium) { if (success != null || error != null) Interlocked.Increment(ref m_childrenCount); @@ -759,10 +753,10 @@ namespace Implab { #region IPromiseBase explicit implementation - IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) { + IPromise IPromise.Then(Action success, Action error, Action cancel) { return Then( - success != null ? new ResultHandler(x => success()) : null, - error != null ? new ErrorHandler(e => { + success != null ? new Action(x => success()) : null, + error != null ? new Func(e => { error(e); return default(T); }) : null, @@ -770,10 +764,10 @@ namespace Implab { ); } - IPromise IPromise.Then(Action success, ErrorHandler error) { + IPromise IPromise.Then(Action success, Action error) { return Then( - success != null ? new ResultHandler(x => success()) : null, - error != null ? new ErrorHandler(e => { + success != null ? new Action(x => success()) : null, + error != null ? new Func(e => { error(e); return default(T); }) : null @@ -785,16 +779,16 @@ namespace Implab { return Then(x => success()); } - IPromise IPromise.Chain(Func chained, ErrorHandler error, Action cancel) { + IPromise IPromise.Chain(Func chained, Func error, Action cancel) { return ChainNoResult(chained, error, cancel); } - IPromise ChainNoResult(Func chained, ErrorHandler error, Action cancel) { + IPromise ChainNoResult(Func chained, Func error, Action cancel) { Safe.ArgumentNotNull(chained, "chained"); - var medium = new Promise(this, true); + var medium = new Promise(this); - ResultHandler resultHandler = delegate(T result) { + Action resultHandler = delegate { if (medium.IsCancelled) return; @@ -815,7 +809,7 @@ namespace Implab { }); }; - ErrorHandler errorHandler; + Func errorHandler; if (error != null) errorHandler = delegate(Exception e) { @@ -866,7 +860,7 @@ namespace Implab { return medium; } - IPromise IPromise.Chain(Func chained, ErrorHandler error) { + IPromise IPromise.Chain(Func chained, Func error) { return ChainNoResult(chained, error, null); } IPromise IPromise.Chain(Func chained) { @@ -874,11 +868,11 @@ namespace Implab { } - void IPromise.Last(Action success, ErrorHandler error, Action cancel) { + void IPromise.Last(Action success, Action error, Action cancel) { Last(x => success(), error, cancel); } - void IPromise.Last(Action success, ErrorHandler error) { + void IPromise.Last(Action success, Action error) { Last(x => success(), error, null); } @@ -886,7 +880,7 @@ namespace Implab { Last(x => success(), null, null); } - IPromise IPromise.Error(ErrorHandler error) { + IPromise IPromise.Error(Action error) { return Error(error); } diff --git a/Implab/PromiseExtensions.cs b/Implab/PromiseExtensions.cs --- a/Implab/PromiseExtensions.cs +++ b/Implab/PromiseExtensions.cs @@ -12,7 +12,7 @@ namespace Implab { if (context == null) return that; - var p = new SyncContextPromise(context, that, true); + var p = new SyncContextPromise(context, that); that.Last( p.Resolve, @@ -26,7 +26,7 @@ namespace Implab { Safe.ArgumentNotNull(that, "that"); Safe.ArgumentNotNull(context, "context"); - var p = new SyncContextPromise(context, that, true); + var p = new SyncContextPromise(context, that); that.Last( p.Resolve, @@ -36,6 +36,24 @@ namespace Implab { return p; } + /// + /// Ensures the dispatched. + /// + /// The dispatched. + /// That. + /// Head. + /// Cleanup. + /// The 1st type parameter. + /// The 2nd type parameter. + public static TPromise EnsureDispatched(this TPromise that, IPromise head, Action 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(this Promise that, Func callback) { Safe.ArgumentNotNull(that, "that"); Safe.ArgumentNotNull(callback, "callback"); diff --git a/Implab/SyncContextPromise.cs b/Implab/SyncContextPromise.cs --- a/Implab/SyncContextPromise.cs +++ b/Implab/SyncContextPromise.cs @@ -9,8 +9,8 @@ namespace Implab { 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; }