Ver código fonte

Implement TaskFactory::FromAsync for calls completed synchronously.

Marek Safar 13 anos atrás
pai
commit
7c3708d2ba

+ 16 - 4
mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs

@@ -339,7 +339,10 @@ namespace System.Threading.Tasks
 				throw new ArgumentOutOfRangeException ("creationOptions");
 
 			var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
-			beginMethod (l => InnerInvoke (tcs, endMethod, l), state);
+			var iar = beginMethod (l => InnerInvoke (tcs, endMethod, l), state);
+			if (iar != null && iar.CompletedSynchronously) {
+				InnerInvoke (tcs, endMethod, iar);
+			}
 
 			return tcs.Task;
 		}
@@ -370,7 +373,10 @@ namespace System.Threading.Tasks
 				throw new ArgumentOutOfRangeException ("creationOptions");
 
 			var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
-			beginMethod (arg1, l => InnerInvoke (tcs, endMethod, l), state);
+			var iar = beginMethod (arg1, l => InnerInvoke (tcs, endMethod, l), state);
+			if (iar != null && iar.CompletedSynchronously) {
+				InnerInvoke (tcs, endMethod, iar);
+			}
 
 			return tcs.Task;
 		}
@@ -400,7 +406,10 @@ namespace System.Threading.Tasks
 				throw new ArgumentOutOfRangeException ("creationOptions");
 
 			var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
-			beginMethod (arg1, arg2, l => InnerInvoke (tcs, endMethod, l), state);
+			var iar = beginMethod (arg1, arg2, l => InnerInvoke (tcs, endMethod, l), state);
+			if (iar != null && iar.CompletedSynchronously) {
+				InnerInvoke (tcs, endMethod, iar);
+			}
 
 			return tcs.Task;
 		}
@@ -431,7 +440,10 @@ namespace System.Threading.Tasks
 				throw new ArgumentOutOfRangeException ("creationOptions");
 
 			var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
-			beginMethod (arg1, arg2, arg3, l => InnerInvoke (tcs, endMethod, l), state);
+			var iar = beginMethod (arg1, arg2, arg3, l => InnerInvoke (tcs, endMethod, l), state);
+			if (iar != null && iar.CompletedSynchronously) {
+				InnerInvoke (tcs, endMethod, iar);
+			}
 
 			return tcs.Task;
 		}

+ 48 - 0
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest_T.cs

@@ -90,6 +90,34 @@ namespace MonoTests.System.Threading.Tasks
 			}
 		}
 
+		class TestAsyncResultCompletedSynchronously : IAsyncResult
+		{
+			public object AsyncState {
+				get {
+					throw new NotImplementedException ();
+				}
+			}
+
+			public WaitHandle AsyncWaitHandle {
+				get {
+					throw new NotImplementedException ();
+				}
+			}
+
+			public bool CompletedSynchronously {
+				get {
+					return true;
+				}
+			}
+
+			public bool IsCompleted {
+				get {
+					throw new NotImplementedException ();
+				}
+			}
+		}
+		
+
 		[SetUp]
 		public void Setup ()
 		{
@@ -178,6 +206,26 @@ namespace MonoTests.System.Threading.Tasks
 			Assert.IsTrue (task.Wait (1000), "#1");
 			Assert.AreEqual (5, task.Result, "#2");
 		}
+
+		IAsyncResult BeginGetTestAsyncResultCompletedSynchronously (AsyncCallback cb, object obj)
+		{
+			return new TestAsyncResultCompletedSynchronously ();
+		}
+
+		string EndGetTestAsyncResultCompletedSynchronously (IAsyncResult res)
+		{
+			return "1";
+		}
+
+		[Test]
+		public void FromAsync_CompletedSynchronously ()
+		{
+			var factory = new TaskFactory<string> ();
+			var task = factory.FromAsync (BeginGetTestAsyncResultCompletedSynchronously, EndGetTestAsyncResultCompletedSynchronously, null);
+
+			Assert.IsTrue (task.Wait (1000), "#1");
+			Assert.AreEqual ("1", task.Result, "#2");
+		}
 	}
 }