Mercurial > pub > ImplabNet
diff Implab/PromiseExtensions.cs @ 124:a336cb13c6a9 v2
major update, added Drain mathod to AsyncQueue class
author | cin |
---|---|
date | Thu, 15 Jan 2015 02:43:14 +0300 |
parents | 2573b562e328 |
children | e9e7940c7d98 |
line wrap: on
line diff
--- a/Implab/PromiseExtensions.cs Tue Jan 13 01:42:38 2015 +0300 +++ b/Implab/PromiseExtensions.cs Thu Jan 15 02:43:14 2015 +0300 @@ -94,12 +94,18 @@ return that; } - public static IPromise Combine(this ICollection<IPromise> that) { + public static IPromise Bundle(this ICollection<IPromise> that) { Safe.ArgumentNotNull(that, "that"); int count = that.Count; + int errors = 0; var medium = new Promise(); + medium.On(() => { + foreach(var p2 in that) + p2.Cancel(); + }, PromiseEventType.ErrorOrCancel); + foreach (var p in that) p.On( () => { @@ -107,15 +113,62 @@ medium.Resolve(); }, error => { - throw new Exception("The dependency promise is failed", error); + if (Interlocked.Increment(ref errors) == 1) + medium.Reject( + new Exception("The dependency promise is failed", error) + ); }, () => { - throw new OperationCanceledException("The dependency promise is cancelled"); + if (Interlocked.Increment(ref errors) == 1) + medium.Reject( + new Exception("The dependency promise is cancelled") + ); } ); return medium; } + + public static IPromise<T[]> Bundle<T>(this ICollection<IPromise<T>> that) { + Safe.ArgumentNotNull(that, "that"); + + int count = that.Count; + int errors = 0; + var medium = new Promise<T[]>(); + var results = new T[that.Count]; + + medium.On(() => { + foreach(var p2 in that) + p2.Cancel(); + }, PromiseEventType.ErrorOrCancel); + + int i = 0; + foreach (var p in that) { + var idx = i; + p.On( + x => { + results[idx] = x; + if (Interlocked.Decrement(ref count) == 0) + medium.Resolve(results); + }, + error => { + if (Interlocked.Increment(ref errors) == 1) + medium.Reject( + new Exception("The dependency promise is failed", error) + ); + }, + () => { + if (Interlocked.Increment(ref errors) == 1) + medium.Reject( + new Exception("The dependency promise is cancelled") + ); + } + ); + i++; + } + + return medium; + } #if NET_4_5