diff --git a/Implab/Components/ExecutionState.cs b/Implab/Components/ExecutionState.cs --- a/Implab/Components/ExecutionState.cs +++ b/Implab/Components/ExecutionState.cs @@ -13,6 +13,12 @@ Running, + Suspending, + + Suspended, + + Resuming, + Stopping, Failed, diff --git a/Implab/PromiseExtensions.cs b/Implab/PromiseExtensions.cs --- a/Implab/PromiseExtensions.cs +++ b/Implab/PromiseExtensions.cs @@ -180,8 +180,8 @@ namespace Implab { /// A callback used to cleanup already resolved promises in case of an error /// public static IPromise PromiseAll(this ICollection> that, Action cleanup) { - Safe.ArgumentNotNull(that, "that"); - + Safe.ArgumentNotNull(that, "that"); + int count = that.Count; if (count == 0) @@ -263,6 +263,8 @@ namespace Implab { public static IPromise Then(this IPromise that, Func success, Func error, Func cancel) { Safe.ArgumentNotNull(that, "that"); + Safe.ArgumentNotNull(success, "success"); + var d = new FuncTask(success, error, cancel, false); that.On(d.Resolve, d.Reject, d.CancelOperation); d.CancellationRequested(that.Cancel); @@ -276,8 +278,8 @@ namespace Implab { success(x); return x; }, - error, - cancel, + error, + cancel, false ); that.On(d.Resolve, d.Reject, d.CancelOperation); @@ -427,6 +429,13 @@ namespace Implab { #endregion + public static IPromise Guard(this IPromise that, Func, IPromise> continuation, Action cleanup) { + Safe.ArgumentNotNull(that, "that"); + Safe.ArgumentNotNull(continuation, "continuation"); + return continuation(that).Error((err) => { + that.On(cleanup); + }, true); + } #if NET_4_5 @@ -442,6 +451,24 @@ namespace Implab { return new PromiseAwaiter(that); } + public static IPromise BoundCancellationToken(this IPromise that, CancellationToken ct) { + Safe.ArgumentNotNull(that, "that"); + ct.Register(that.Cancel); + return that.Then(null, null, (err) => { + ct.ThrowIfCancellationRequested(); + throw new PromiseTransientException(err); + }); + } + + public static IPromise BoundCancellationToken(this IPromise that, CancellationToken ct) { + Safe.ArgumentNotNull(that, "that"); + ct.Register(that.Cancel); + return that.Then(null, null, (err) => { + ct.ThrowIfCancellationRequested(); + throw new PromiseTransientException(err); + }); + } + #endif } } diff --git a/Implab/Safe.cs b/Implab/Safe.cs --- a/Implab/Safe.cs +++ b/Implab/Safe.cs @@ -127,5 +127,6 @@ namespace Implab return Promise.FromException(err); } } + } }