Browse Source

Merge pull request #117 from anpete/fix-using-enumerator

Fixes concurrent Dispose issue with UsingEnumerator. Builds on 48b540…
PranavSenthilnathan 10 years ago
parent
commit
859e6159cb

+ 1 - 1
Ix.NET/Source/System.Interactive.Async/AsyncEnumerable.Exceptions.cs

@@ -234,7 +234,7 @@ namespace System.Linq
                     (ct, tcs) =>
                     {
                         f(tcs, cts.Token);
-                        return tcs.Task.UsingEnumeratorSync(r);
+                        return tcs.Task.UsingEnumerator(r);
                     },
                     () => e.Current,
                     d.Dispose

+ 5 - 27
Ix.NET/Source/System.Interactive.Async/TaskExt.cs

@@ -60,22 +60,6 @@ namespace System.Threading.Tasks
                 success(task.Result);
         }
 
-        public static Task<bool> UsingEnumerator(this Task<bool> task, IDisposable disposable)
-        {
-            task.ContinueWith(t =>
-            {
-                if (t.IsFaulted)
-                {
-                    var ignored = t.Exception; // don't remove!
-                }
-
-                if (t.IsFaulted || t.IsCanceled || !t.Result)
-                    disposable.Dispose();
-            }, TaskContinuationOptions.ExecuteSynchronously);
-
-            return task;
-        }
-
         public static Task Then<T>(this Task<T> task, Action<Task<T>> continuation)
         {
             //
@@ -96,19 +80,13 @@ namespace System.Threading.Tasks
             return task.ContinueWith(continuation);
         }
 
-        public static Task<bool> UsingEnumeratorSync(this Task<bool> task, IDisposable disposable)
+        public static Task<bool> UsingEnumerator(this Task<bool> task, IDisposable disposable)
         {
-            var tcs = new TaskCompletionSource<bool>();
-
-            task.ContinueWith(t =>
+            return task.Finally(() =>
             {
-                if (t.IsFaulted || t.IsCanceled || !t.Result)
-                    disposable.Dispose(); // TODO: Check whether we need exception handling here!
-
-                t.Handle(tcs, res => tcs.TrySetResult(res));
-            }, TaskContinuationOptions.ExecuteSynchronously);
-
-            return tcs.Task;
+                if (task.IsFaulted || task.IsCanceled || !task.Result)
+                    disposable.Dispose();
+            });
         }
 
         public static Task<R> Finally<R>(this Task<R> task, Action action)