Răsfoiți Sursa

Remove internal continuations from unfinished tasks used in WhenAny, Fixes #11008

Marek Safar 13 ani în urmă
părinte
comite
46fc054c3f

+ 1 - 1
mcs/class/corlib/System.Threading.Tasks/Task.cs

@@ -347,7 +347,7 @@ namespace System.Threading.Tasks
 				continuation.Execute ();
 		}
 
-		void RemoveContinuation (IContinuation continuation)
+		internal void RemoveContinuation (IContinuation continuation)
 		{
 			continuations.Remove (continuation);
 		}

+ 10 - 3
mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs

@@ -256,12 +256,13 @@ namespace System.Threading.Tasks
 	{
 		readonly Task<T> owner;
 		readonly IList<T> tasks;
-		AtomicBooleanValue executed = new AtomicBooleanValue ();
+		AtomicBooleanValue executed;
 
 		public WhenAnyContinuation (Task<T> owner, IList<T> tasks)
 		{
 			this.owner = owner;
 			this.tasks = tasks;
+			executed = new AtomicBooleanValue ();
 		}
 
 		public void Execute ()
@@ -269,13 +270,19 @@ namespace System.Threading.Tasks
 			if (!executed.TryRelaxedSet ())
 				return;
 
+			bool owner_notified = false;
 			for (int i = 0; i < tasks.Count; ++i) {
 				var task = tasks[i];
-				if (!task.IsCompleted)
+				if (!task.IsCompleted) {
+					task.RemoveContinuation (this);
+					continue;
+				}
+
+				if (owner_notified)
 					continue;
 
 				owner.TrySetResult (task);
-				return;
+				owner_notified = true;
 			}
 		}
 	}