Better handling of OperationCanceledException
authorMarek Safar <marek.safar@gmail.com>
Tue, 3 Apr 2012 11:17:07 +0000 (12:17 +0100)
committerMarek Safar <marek.safar@gmail.com>
Tue, 3 Apr 2012 12:43:19 +0000 (13:43 +0100)
mcs/class/corlib/System.Runtime.CompilerServices/AsyncTaskMethodBuilder.cs
mcs/class/corlib/System.Runtime.CompilerServices/AsyncTaskMethodBuilder_T.cs
mcs/tests/test-async-32.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index fb10ef97c63f305122338a87307883afbcdd254f..197ece5adc9ab9a5c6a9b1f72df9cd16bbd04434 100644 (file)
@@ -76,8 +76,15 @@ namespace System.Runtime.CompilerServices
                
                public void SetException (Exception exception)
                {
-                       if (!task.TrySetException (new AggregateException (exception)))
-                               throw new InvalidOperationException ("The task has already completed");
+                       if (exception is OperationCanceledException) {
+                               if (Task.TrySetCanceled ())
+                                       return;
+                       } else {
+                               if (Task.TrySetException (new AggregateException (exception)))
+                                       return;
+                       }
+
+                       throw new InvalidOperationException ("The task has already completed");
                }
 
                public void SetStateMachine (IAsyncStateMachine stateMachine)
index 71cbb214ce6a5ef2619a12584e7be4c821d24774..f955d6b9fd57a3cfbe4b94965d9635bf5c3d0b4d 100644 (file)
@@ -76,8 +76,15 @@ namespace System.Runtime.CompilerServices
 
                public void SetException (Exception exception)
                {
-                       if (!task.TrySetException (new AggregateException (exception)))
-                               throw new InvalidOperationException ("The task has already completed");
+                       if (exception is OperationCanceledException) {
+                               if (Task.TrySetCanceled ())
+                                       return;
+                       } else {
+                               if (Task.TrySetException (new AggregateException (exception)))
+                                       return;
+                       }
+
+                       throw new InvalidOperationException ("The task has already completed");
                }
 
                public void SetStateMachine (IAsyncStateMachine stateMachine)
diff --git a/mcs/tests/test-async-32.cs b/mcs/tests/test-async-32.cs
new file mode 100644 (file)
index 0000000..7c31992
--- /dev/null
@@ -0,0 +1,69 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+class Program
+{
+       static async Task<int> TestCanceled()
+       {
+               await Task.FromResult(1);
+               throw new OperationCanceledException();
+       }
+
+       static async Task TestCanceled_2()
+       {
+               await Task.FromResult(1);
+               throw new OperationCanceledException();
+       }
+
+       static async Task<int> TestException()
+       {
+               await Task.FromResult(1);
+               throw new ApplicationException();
+       }
+
+       static int Main()
+       {
+               bool canceled = false;
+               var t = TestCanceled().ContinueWith(l =>
+               {
+                       canceled = l.IsCanceled;
+               }, TaskContinuationOptions.ExecuteSynchronously);
+
+               t.Wait();
+
+               if (!canceled)
+                       return 1;
+
+               if (t.Exception != null)
+                       return 2;
+
+               t = TestCanceled_2().ContinueWith(l =>
+               {
+                       canceled = l.IsCanceled;
+               }, TaskContinuationOptions.ExecuteSynchronously);
+
+               t.Wait();
+
+               if (!canceled)
+                       return 11;
+
+               if (t.Exception != null)
+                       return 12;
+
+               bool faulted = false;
+               t = TestException().ContinueWith(l =>
+               {
+                       faulted = l.IsFaulted;
+               }, TaskContinuationOptions.ExecuteSynchronously);
+
+               if (!faulted)
+                       return 21;
+
+               if (t.Exception != null)
+                       return 22;
+
+               Console.WriteLine("ok");
+               return 0;
+       }
+}
index 33a35dd5736eb5d869b02fa15fc42fb5fc423ad4..be6e6d9ed9e82c4c2d7c0815ec9ff8e1840ea57b 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-async-32.cs">
+    <type name="Program">
+      <method name="System.Threading.Tasks.Task`1[System.Int32] TestCanceled()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="System.Threading.Tasks.Task TestCanceled_2()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.Int32] TestException()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="Int32 Main()" attrs="145">
+        <size>248</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Program+&lt;TestCanceled&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>160</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Program+&lt;TestCanceled_2&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>159</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Program+&lt;TestException&gt;c__async2">
+      <method name="Void MoveNext()" attrs="486">
+        <size>160</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Program+&lt;Main&gt;c__AnonStorey3">
+      <method name="Void &lt;&gt;m__0(System.Threading.Tasks.Task`1[System.Int32])" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Void &lt;&gt;m__1(System.Threading.Tasks.Task)" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Void &lt;&gt;m__2(System.Threading.Tasks.Task`1[System.Int32])" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">