Implement TaskFactory::FromAsync for calls completed synchronously.
authorMarek Safar <marek.safar@gmail.com>
Tue, 2 Oct 2012 16:03:15 +0000 (17:03 +0100)
committerMarek Safar <marek.safar@gmail.com>
Tue, 2 Oct 2012 16:03:15 +0000 (17:03 +0100)
mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest_T.cs

index af9ff6fe122088829f7118fee3053873b78197d3..28f5c365ed6a98f554db86f37077a7b1a5a88d91 100644 (file)
@@ -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;
                }
index b8c3776d5fdda4eb36bd46272c49be4892f8bac1..3fe032f20c639e23229478d870089c4276e09c46 100644 (file)
@@ -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");
+               }
        }
 }