[mono/mono] cf2ac217: Make Task.Delay more reliable. Fixes #14585

"Marek Safar ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014197247f1c-9731f2c4-dc4d-42ee-b67f-8995c5a8862b-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/c82aea5fb21a...cf2ac2171b7d

   Commit: cf2ac2171b7d539d5edc6a986013f5befbaa444a
   Author: Marek Safar <[email protected]> (marek-safar)
     Date: 2013-10-08 08:16:19 GMT
      URL: https://github.com/mono/mono/commit/cf2ac2171b7d539d5edc6a986013f5befbaa444a

Make Task.Delay more reliable. Fixes #14585

Changed paths:
  M mcs/class/corlib/System.Threading.Tasks/Task.cs
  M mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs
  M mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs

Modified: mcs/class/corlib/System.Threading.Tasks/Task.cs
===================================================================
@@ -957,11 +957,23 @@ public static Task Delay (int millisecondsDelay, CancellationToken cancellationT
 			if (millisecondsDelay < -1)
 				throw new ArgumentOutOfRangeException ("millisecondsDelay");
 
-			var task = new Task (TaskActionInvoker.Delay, millisecondsDelay, cancellationToken, TaskCreationOptions.None, null, TaskConstants.Finished);
+			if (cancellationToken.IsCancellationRequested)
+				return TaskConstants.Canceled;
+
+			var task = new Task (TaskActionInvoker.Empty, null, cancellationToken, TaskCreationOptions.None, null, null);
 			task.SetupScheduler (TaskScheduler.Default);
-			
-			if (millisecondsDelay != Timeout.Infinite)
-				task.scheduler.QueueTask (task);
+
+			if (millisecondsDelay != Timeout.Infinite) {
+				var timer = new Timer (delegate (object state) {
+					var t = (Task) state;
+					if (t.Status == TaskStatus.WaitingForActivation) {
+						t.Status = TaskStatus.Running;
+						t.Finish ();
+					}
+				}, task, millisecondsDelay, -1);
+
+				task.ContinueWith (new DisposeContinuation (timer));
+			}
 
 			return task;
 		}

Modified: mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs
===================================================================
@@ -338,6 +338,21 @@ public void Execute ()
 			evt.Signal ();
 		}
 	}
+
+	sealed class DisposeContinuation : IContinuation
+	{
+		readonly IDisposable instance;
+
+		public DisposeContinuation (IDisposable instance)
+		{
+			this.instance = instance;
+		}
+
+		public void Execute ()
+		{
+			instance.Dispose ();
+		}
+	}
 }
 
 #endif

Modified: mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
===================================================================
@@ -1126,6 +1126,15 @@ public void Delay_Cancelled ()
 		}
 
 		[Test]
+		public void Delay_TimeManagement ()
+		{
+			var delay1 = Task.Delay(50);
+			var delay2 = Task.Delay(25);
+			Assert.IsTrue (Task.WhenAny(new[] { delay1, delay2 }).Wait (1000));
+			Assert.AreEqual (TaskStatus.RanToCompletion, delay2.Status);
+		}
+
+		[Test]
 		public void WaitAny_WithNull ()
 		{
 			var tasks = new [] {


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.