[corlib] Add check for launching cancelled task to all overloads
authorMarek Safar <marek.safar@gmail.com>
Sat, 7 Dec 2013 14:40:52 +0000 (15:40 +0100)
committerMarek Safar <marek.safar@gmail.com>
Sat, 7 Dec 2013 18:51:35 +0000 (19:51 +0100)
mcs/class/corlib/System.Threading.Tasks/TaskFactory.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest_T.cs

index 607f08da4ec4652c97ea9c82dbb4ae905e53813d..a558c622c5ebf2cf5a3158394a86ecd9da609966 100644 (file)
@@ -214,9 +214,14 @@ namespace System.Threading.Tasks
                                                        TaskCreationOptions creationOptions,
                                                        TaskScheduler scheduler)
                {
-                       Task<TResult> t = new Task<TResult> (function, state, cancellationToken, creationOptions);
-                       t.Start (scheduler);
+                       var t = new Task<TResult> (function, state, cancellationToken, creationOptions);
                        
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
+
                        return t;
                }
                #endregion
index f0f87a898f2868de95cf2e7d324f6e7cdaf08c4e..857841e326ff72a4535ffcd095975c31b2c6857f 100644 (file)
@@ -604,16 +604,24 @@ namespace MonoTests.System.Threading.Tasks
                [Test]
                public void StartNewCancelled ()
                {
-                       var cts = new CancellationTokenSource ();
-                       cts.Cancel ();
+                       var ct = new CancellationToken (true);
 
-                       var task = factory.StartNew (() => Assert.Fail ("Should never be called"), cts.Token);
+                       var task = factory.StartNew (() => Assert.Fail ("Should never be called"), ct);
                        try {
                                task.Start ();
+                               Assert.Fail ("#1");
                        } catch (InvalidOperationException) {
                        }
 
                        Assert.IsTrue (task.IsCanceled, "#2");
+
+                       task = factory.StartNew (() => { }, ct);
+                       try {
+                               task.Wait ();
+                       } catch (AggregateException e) {
+                               Assert.IsTrue (task.IsCanceled, "#3");
+                               Assert.That (e.InnerException, Is.TypeOf (typeof (TaskCanceledException)), "#4");
+                       }
                }
        }
 }
index 0c30a093b03e1f30e010b5b4141f1794cffb6118..ff964bb9cfcc65e348b234958455b37394d8e901 100644 (file)
@@ -33,6 +33,9 @@ using System.Threading;
 using System.Threading.Tasks;
 
 using NUnit.Framework;
+#if !MOBILE
+using NUnit.Framework.SyntaxHelpers;
+#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
@@ -249,6 +252,29 @@ namespace MonoTests.System.Threading.Tasks
                        Assert.AreEqual ("1", task.Result, "#2");
                }
 
+               [Test]
+               public void StartNewCancelled ()
+               {
+                       var ct = new CancellationToken (true);
+                       var factory = new TaskFactory<int> ();
+
+                       var task = factory.StartNew (() => { Assert.Fail ("Should never be called"); return 1; }, ct);
+                       try {
+                               task.Start ();
+                               Assert.Fail ("#1");
+                       } catch (InvalidOperationException) {
+                       }
+
+                       Assert.IsTrue (task.IsCanceled, "#2");
+
+                       task = factory.StartNew (() => 1, ct);
+                       try {
+                               task.Wait ();
+                       } catch (AggregateException e) {
+                               Assert.IsTrue (task.IsCanceled, "#3");
+                               Assert.That (e.InnerException, Is.TypeOf (typeof (TaskCanceledException)), "#4");
+                       }
+               }
        }
 }