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