4 // Copyright (c) 2008 Jérémie "Garuma" Laval
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 using System.Threading;
30 using System.Threading.Tasks;
32 using NUnit.Framework;
34 namespace MonoTests.System.Threading.Tasks
37 public class TaskTests
45 tasks = new Task[max];
48 void InitWithDelegate(Action action)
50 for (int i = 0; i < max; i++) {
51 tasks[i] = Task.Factory.StartNew(action);
56 public void WaitAnyTest()
58 ParallelTestHelper.Repeat (delegate {
62 InitWithDelegate(delegate {
63 int times = Interlocked.Exchange (ref flag, 1);
65 SpinWait sw = new SpinWait ();
66 while (finished == 0) sw.SpinOnce ();
68 Interlocked.Increment (ref finished);
72 int index = Task.WaitAny(tasks, 1000);
74 Assert.AreNotEqual (-1, index, "#3");
75 Assert.AreEqual (1, flag, "#1");
76 Assert.AreEqual (1, finished, "#2");
81 public void WaitAny_Empty ()
83 Assert.AreEqual (-1, Task.WaitAny (new Task[0]));
87 public void WaitAny_Zero ()
89 Assert.AreEqual (-1, Task.WaitAny (new[] { new Task (delegate { })}, 0), "#1");
90 Assert.AreEqual (-1, Task.WaitAny (new[] { new Task (delegate { }) }, 20), "#1");
94 public void WaitAny_Cancelled ()
96 var cancelation = new CancellationTokenSource ();
97 var tasks = new Task[] {
98 new Task (delegate { }),
99 new Task (delegate { }, cancelation.Token)
102 cancelation.Cancel ();
104 Assert.AreEqual (1, Task.WaitAny (tasks, 1000), "#1");
105 Assert.IsTrue (tasks[1].IsCompleted, "#2");
106 Assert.IsTrue (tasks[1].IsCanceled, "#3");
110 public void WaitAny_CancelledWithoutExecution ()
112 var cancelation = new CancellationTokenSource ();
113 var tasks = new Task[] {
114 new Task (delegate { }),
115 new Task (delegate { })
119 var mre = new ManualResetEventSlim (false);
120 ThreadPool.QueueUserWorkItem (delegate {
121 res = Task.WaitAny (tasks, 20);
125 cancelation.Cancel ();
126 Assert.IsTrue (mre.Wait (1000), "#1");
127 Assert.AreEqual (-1, res);
131 public void WaitAny_OneException ()
133 var mre = new ManualResetEventSlim (false);
134 var tasks = new Task[] {
135 Task.Factory.StartNew (delegate { mre.Wait (1000); }),
136 Task.Factory.StartNew (delegate { throw new ApplicationException (); })
139 Assert.AreEqual (1, Task.WaitAny (tasks, 1000), "#1");
140 Assert.IsFalse (tasks[0].IsCompleted, "#2");
141 Assert.IsTrue (tasks[1].IsFaulted, "#3");
147 public void WaitAny_SingleCanceled ()
149 var src = new CancellationTokenSource ();
150 var t = Task.Factory.StartNew (() => { Thread.Sleep (200); src.Cancel (); src.Token.ThrowIfCancellationRequested (); }, src.Token);
151 Assert.AreEqual (0, Task.WaitAny (new [] { t }));
154 public void WaitAny_ManyExceptions ()
156 CountdownEvent cde = new CountdownEvent (3);
158 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } }),
159 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } }),
160 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } })
163 Assert.IsTrue (cde.Wait (1000), "#1");
166 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#2");
167 } catch (AggregateException e) {
168 Assert.AreEqual (3, e.InnerExceptions.Count, "#3");
173 public void WaitAny_ManyCanceled ()
175 var cancellation = new CancellationToken (true);
177 Task.Factory.StartNew (delegate { }, cancellation),
178 Task.Factory.StartNew (delegate { }, cancellation),
179 Task.Factory.StartNew (delegate { }, cancellation)
183 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#1");
184 } catch (AggregateException e) {
185 Assert.AreEqual (3, e.InnerExceptions.Count, "#2");
190 public void WaitAllTest ()
192 ParallelTestHelper.Repeat (delegate {
194 InitWithDelegate(delegate { Interlocked.Increment(ref achieved); });
196 Assert.AreEqual(max, achieved, "#1");
201 public void WaitAll_ManyTasks ()
203 for (int r = 0; r < 2000; ++r) {
204 var tasks = new Task[60];
206 for (int i = 0; i < tasks.Length; i++) {
207 tasks[i] = Task.Factory.StartNew (delegate { Thread.Sleep (0); });
210 Assert.IsTrue (Task.WaitAll (tasks, 2000));
215 public void WaitAll_Zero ()
217 Assert.IsFalse (Task.WaitAll (new Task[1] { new Task (delegate { }) }, 0), "#0");
218 Assert.IsFalse (Task.WaitAll (new Task[1] { new Task (delegate { }) }, 10), "#1");
222 public void WaitAll_WithExceptions ()
224 InitWithDelegate (delegate { throw new ApplicationException (); });
227 Task.WaitAll (tasks);
229 } catch (AggregateException e) {
230 Assert.AreEqual (6, e.InnerExceptions.Count, "#2");
233 Assert.IsNotNull (tasks[0].Exception, "#3");
237 public void WaitAll_TimeoutWithExceptionsAfter ()
239 CountdownEvent cde = new CountdownEvent (2);
240 var mre = new ManualResetEvent (false);
242 Task.Factory.StartNew (delegate { mre.WaitOne (); }),
243 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } }),
244 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } })
247 Assert.IsTrue (cde.Wait (1000), "#1");
248 Assert.IsFalse (Task.WaitAll (tasks, 1000), "#2");
253 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#3");
255 } catch (AggregateException e) {
256 Assert.AreEqual (2, e.InnerExceptions.Count, "#5");
261 public void WaitAll_TimeoutWithExceptionsBefore ()
263 CountdownEvent cde = new CountdownEvent (2);
264 var mre = new ManualResetEvent (false);
266 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } }),
267 Task.Factory.StartNew (delegate { try { throw new ApplicationException (); } finally { cde.Signal (); } }),
268 Task.Factory.StartNew (delegate { mre.WaitOne (); })
271 Assert.IsTrue (cde.Wait (1000), "#1");
272 Assert.IsFalse (Task.WaitAll (tasks, 1000), "#2");
277 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#3");
279 } catch (AggregateException e) {
280 Assert.AreEqual (2, e.InnerExceptions.Count, "#5");
285 public void WaitAll_Cancelled ()
287 var cancelation = new CancellationTokenSource ();
288 var tasks = new Task[] {
289 new Task (delegate { cancelation.Cancel (); }),
290 new Task (delegate { }, cancelation.Token)
296 Task.WaitAll (tasks);
298 } catch (AggregateException e) {
299 var inner = (TaskCanceledException) e.InnerException;
300 Assert.AreEqual (tasks[1], inner.Task, "#2");
303 Assert.IsTrue (tasks[0].IsCompleted, "#3");
304 Assert.IsTrue (tasks[1].IsCanceled, "#4");
308 public void WaitAllExceptionThenCancelled ()
310 var cancelation = new CancellationTokenSource ();
311 var tasks = new Task[] {
312 new Task (delegate { cancelation.Cancel (); throw new ApplicationException (); }),
313 new Task (delegate { }, cancelation.Token)
319 Task.WaitAll (tasks);
321 } catch (AggregateException e) {
322 Assert.IsInstanceOfType (typeof (ApplicationException), e.InnerException, "#2");
323 var inner = (TaskCanceledException) e.InnerExceptions[1];
324 Assert.AreEqual (tasks[1], inner.Task, "#3");
327 Assert.IsTrue (tasks[0].IsCompleted, "#4");
328 Assert.IsTrue (tasks[1].IsCanceled, "#5");
332 public void WaitAll_StartedUnderWait ()
334 var task1 = new Task (delegate { });
336 ThreadPool.QueueUserWorkItem (delegate {
337 // Sleep little to let task to start and hit internal wait
342 Assert.IsTrue (Task.WaitAll (new [] { task1 }, 1000), "#1");
346 public void CancelBeforeStart ()
348 var src = new CancellationTokenSource ();
350 Task t = new Task (delegate { }, src.Token);
352 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#1");
357 } catch (InvalidOperationException) {
362 public void Wait_CancelledTask ()
364 var src = new CancellationTokenSource ();
366 Task t = new Task (delegate { }, src.Token);
372 } catch (AggregateException e) {
373 var details = (TaskCanceledException) e.InnerException;
374 Assert.AreEqual (t, details.Task, "#1e");
380 } catch (AggregateException e) {
381 var details = (TaskCanceledException) e.InnerException;
382 Assert.AreEqual (t, details.Task, "#2e");
383 Assert.IsNull (details.Task.Exception, "#2e2");
387 [Test, ExpectedException (typeof (InvalidOperationException))]
388 public void CreationWhileInitiallyCanceled ()
390 var token = new CancellationToken (true);
391 var task = new Task (() => { }, token);
392 Assert.AreEqual (TaskStatus.Canceled, task.Status);
397 public void ContinueWithInvalidArguments ()
399 var task = new Task (() => { });
401 task.ContinueWith (null);
403 } catch (ArgumentException) {
407 task.ContinueWith (delegate { }, null);
409 } catch (ArgumentException) {
413 task.ContinueWith (delegate { }, TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.NotOnCanceled);
415 } catch (ArgumentException) {
419 task.ContinueWith (delegate { }, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion);
421 } catch (ArgumentException) {
426 public void ContinueWithOnAnyTestCase()
428 ParallelTestHelper.Repeat (delegate {
431 Task t = Task.Factory.StartNew(delegate { });
432 Task cont = t.ContinueWith(delegate { result = true; }, TaskContinuationOptions.None);
433 Assert.IsTrue (t.Wait (2000), "First wait, (status, {0})", t.Status);
434 Assert.IsTrue (cont.Wait(2000), "Cont wait, (result, {0}) (parent status, {2}) (status, {1})", result, cont.Status, t.Status);
435 Assert.IsNull(cont.Exception, "#1");
436 Assert.IsNotNull(cont, "#2");
437 Assert.IsTrue(result, "#3");
442 public void ContinueWithOnCompletedSuccessfullyTestCase()
444 ParallelTestHelper.Repeat (delegate {
447 Task t = Task.Factory.StartNew(delegate { });
448 Task cont = t.ContinueWith(delegate { result = true; }, TaskContinuationOptions.OnlyOnRanToCompletion);
449 Assert.IsTrue (t.Wait(1000), "#4");
450 Assert.IsTrue (cont.Wait(1000), "#5");
452 Assert.IsNull(cont.Exception, "#1");
453 Assert.IsNotNull(cont, "#2");
454 Assert.IsTrue(result, "#3");
459 public void ContinueWithOnAbortedTestCase()
462 bool taskResult = false;
464 CancellationTokenSource src = new CancellationTokenSource ();
465 Task t = new Task (delegate { taskResult = true; }, src.Token);
467 Task cont = t.ContinueWith (delegate { result = true; },
468 TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.ExecuteSynchronously);
472 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#1a");
473 Assert.IsTrue (cont.IsCompleted, "#1b");
474 Assert.IsTrue (result, "#1c");
479 } catch (InvalidOperationException) {
482 Assert.IsTrue (cont.Wait (1000), "#3");
484 Assert.IsFalse (taskResult, "#4");
486 Assert.IsNull (cont.Exception, "#5");
487 Assert.AreEqual (TaskStatus.RanToCompletion, cont.Status, "#6");
491 public void ContinueWithOnFailedTestCase()
493 ParallelTestHelper.Repeat (delegate {
496 Task t = Task.Factory.StartNew(delegate { throw new Exception("foo"); });
497 Task cont = t.ContinueWith(delegate { result = true; }, TaskContinuationOptions.OnlyOnFaulted);
499 Assert.IsTrue (cont.Wait(1000), "#0");
500 Assert.IsNotNull (t.Exception, "#1");
501 Assert.IsNotNull (cont, "#2");
502 Assert.IsTrue (result, "#3");
507 public void ContinueWithWithStart ()
509 Task t = new Task<int> (() => 1);
510 t = t.ContinueWith (l => { });
514 } catch (InvalidOperationException) {
519 public void ContinueWithChildren ()
521 ParallelTestHelper.Repeat (delegate {
524 var t = Task.Factory.StartNew (() => Task.Factory.StartNew (() => {}, TaskCreationOptions.AttachedToParent));
526 var mre = new ManualResetEvent (false);
527 t.ContinueWith (l => {
532 Assert.IsTrue (mre.WaitOne (1000), "#1");
533 Assert.IsTrue (result, "#2");
538 public void ContinueWithDifferentOptionsAreCanceledTest ()
540 var mre = new ManualResetEventSlim ();
541 var task = Task.Factory.StartNew (() => mre.Wait (200));
542 var contFailed = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnFaulted);
543 var contCanceled = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnCanceled);
544 var contSuccess = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnRanToCompletion);
547 contSuccess.Wait (100);
549 Assert.IsTrue (contSuccess.IsCompleted);
550 Assert.IsTrue (contFailed.IsCompleted);
551 Assert.IsTrue (contCanceled.IsCompleted);
552 Assert.IsFalse (contSuccess.IsCanceled);
553 Assert.IsTrue (contFailed.IsCanceled);
554 Assert.IsTrue (contCanceled.IsCanceled);
558 public void MultipleTasks()
560 ParallelTestHelper.Repeat (delegate {
561 bool r1 = false, r2 = false, r3 = false;
563 Task t1 = Task.Factory.StartNew(delegate {
566 Task t2 = Task.Factory.StartNew(delegate {
569 Task t3 = Task.Factory.StartNew(delegate {
577 Assert.IsTrue(r1, "#1");
578 Assert.IsTrue(r2, "#2");
579 Assert.IsTrue(r3, "#3");
584 public void WaitChildTestCase()
586 ParallelTestHelper.Repeat (delegate {
587 bool r1 = false, r2 = false, r3 = false;
588 var mre = new ManualResetEventSlim (false);
589 var mreStart = new ManualResetEventSlim (false);
591 Task t = Task.Factory.StartNew(delegate {
592 Task.Factory.StartNew(delegate {
595 }, TaskCreationOptions.AttachedToParent);
596 Task.Factory.StartNew(delegate {
598 }, TaskCreationOptions.AttachedToParent);
599 Task.Factory.StartNew(delegate {
601 }, TaskCreationOptions.AttachedToParent);
606 Assert.IsFalse (t.Wait (10), "#0a");
608 Assert.IsTrue (t.Wait (500), "#0b");
609 Assert.IsTrue(r2, "#1");
610 Assert.IsTrue(r3, "#2");
611 Assert.IsTrue(r1, "#3");
612 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#4");
617 public void WaitChildWithContinuationAttachedTest ()
620 var task = new Task(() =>
622 Task.Factory.StartNew(() => {
624 }, TaskCreationOptions.AttachedToParent).ContinueWith(t => {
627 }, TaskContinuationOptions.AttachedToParent);
631 Assert.IsTrue (result);
635 public void WaitChildWithContinuationNotAttachedTest ()
637 var task = new Task(() =>
639 Task.Factory.StartNew(() => {
641 }, TaskCreationOptions.AttachedToParent).ContinueWith(t => {
646 Assert.IsTrue (task.Wait(400));
650 public void WaitChildWithNesting ()
653 var t = Task.Factory.StartNew (() => {
654 Task.Factory.StartNew (() => {
655 Task.Factory.StartNew (() => {
658 }, TaskCreationOptions.AttachedToParent);
659 }, TaskCreationOptions.AttachedToParent);
662 Assert.IsTrue (result);
666 public void DoubleWaitTest ()
668 ParallelTestHelper.Repeat (delegate {
669 Console.WriteLine ("run");
670 var evt = new ManualResetEventSlim ();
671 var t = Task.Factory.StartNew (() => evt.Wait (2000));
672 var cntd = new CountdownEvent (2);
674 bool r1 = false, r2 = false;
675 ThreadPool.QueueUserWorkItem (delegate { cntd.Signal (); r1 = t.Wait (1000); Console.WriteLine ("out 1 {0}", r1); cntd.Signal (); });
676 ThreadPool.QueueUserWorkItem (delegate { cntd.Signal (); r2 = t.Wait (1000); Console.WriteLine ("out 2 {0}", r2); cntd.Signal (); });
688 public void DoubleTimeoutedWaitTest ()
690 var evt = new ManualResetEventSlim ();
691 var t = new Task (delegate { });
692 var cntd = new CountdownEvent (2);
694 bool r1 = false, r2 = false;
695 ThreadPool.QueueUserWorkItem (delegate { r1 = !t.Wait (100); cntd.Signal (); });
696 ThreadPool.QueueUserWorkItem (delegate { r2 = !t.Wait (100); cntd.Signal (); });
704 public void ExecuteSynchronouslyTest ()
707 Task t = new Task (() => { Thread.Sleep (100); val = 1; });
708 t.RunSynchronously ();
710 Assert.AreEqual (1, val);
714 public void RunSynchronouslyArgumentChecks ()
716 Task t = new Task (() => { });
718 t.RunSynchronously (null);
720 } catch (ArgumentNullException) {
725 public void RunSynchronouslyWithAttachedChildren ()
728 var t = new Task (() => {
729 Task.Factory.StartNew (() => { Thread.Sleep (500); result = true; }, TaskCreationOptions.AttachedToParent);
731 t.RunSynchronously ();
732 Assert.IsTrue (result);
736 public void UnobservedExceptionOnFinalizerThreadTest ()
738 bool wasCalled = false;
739 TaskScheduler.UnobservedTaskException += (o, args) => {
743 var inner = new ApplicationException ();
744 Task.Factory.StartNew (() => { throw inner; });
748 GC.WaitForPendingFinalizers ();
750 Assert.IsTrue (wasCalled);
753 [Test, ExpectedException (typeof (InvalidOperationException))]
754 public void StartFinishedTaskTest ()
756 var t = Task.Factory.StartNew (delegate () { });
763 public void Start_NullArgument ()
765 var t = Task.Factory.StartNew (delegate () { });
769 } catch (ArgumentNullException) {
773 [Test, ExpectedException (typeof (InvalidOperationException))]
774 public void DisposeUnstartedTest ()
776 var t = new Task (() => { });
781 public void ThrowingUnrelatedCanceledExceptionTest ()
783 Task t = new Task (() => {
784 throw new TaskCanceledException ();
787 t.RunSynchronously ();
788 Assert.IsTrue (t.IsFaulted);
789 Assert.IsFalse (t.IsCanceled);
793 public void CanceledContinuationExecuteSynchronouslyTest ()
795 var source = new CancellationTokenSource();
796 var token = source.Token;
797 var evt = new ManualResetEventSlim ();
801 var task = Task.Factory.StartNew (() => evt.Wait (100));
802 var cont = task.ContinueWith (t => result = true, token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
809 } catch (Exception ex) {
813 Assert.IsTrue (task.IsCompleted);
814 Assert.IsTrue (cont.IsCanceled);
815 Assert.IsFalse (result);
816 Assert.IsTrue (thrown);
820 public void WhenChildTaskErrorIsThrownParentTaskShouldBeFaulted ()
822 Task innerTask = null;
823 var testTask = new Task (() =>
825 innerTask = new Task (() =>
827 throw new InvalidOperationException ();
828 }, TaskCreationOptions.AttachedToParent);
829 innerTask.RunSynchronously ();
831 testTask.RunSynchronously ();
833 Assert.AreNotEqual (TaskStatus.Running, testTask.Status);
834 Assert.IsNotNull (innerTask);
835 Assert.IsTrue (innerTask.IsFaulted);
836 Assert.IsNotNull (testTask.Exception);
837 Assert.IsTrue (testTask.IsFaulted);
838 Assert.IsNotNull (innerTask.Exception);
842 public void WhenChildTaskErrorIsThrownOnlyOnFaultedContinuationShouldExecute ()
844 var continuationRan = false;
845 var testTask = new Task (() =>
847 var task = new Task (() =>
849 throw new InvalidOperationException();
850 }, TaskCreationOptions.AttachedToParent);
851 task.RunSynchronously ();
853 var onErrorTask = testTask.ContinueWith (x => continuationRan = true, TaskContinuationOptions.OnlyOnFaulted);
854 testTask.RunSynchronously ();
855 onErrorTask.Wait (100);
856 Assert.IsTrue (continuationRan);
860 public void WhenChildTaskErrorIsThrownNotOnFaultedContinuationShouldNotBeExecuted ()
862 var continuationRan = false;
863 var testTask = new Task (() =>
865 var task = new Task (() =>
867 throw new InvalidOperationException();
868 }, TaskCreationOptions.AttachedToParent);
869 task.RunSynchronously();
871 var onErrorTask = testTask.ContinueWith (x => continuationRan = true, TaskContinuationOptions.NotOnFaulted);
872 testTask.RunSynchronously ();
873 Assert.IsTrue (onErrorTask.IsCompleted);
874 Assert.IsFalse (onErrorTask.IsFaulted);
875 Assert.IsFalse (continuationRan);
879 public void WhenChildTaskSeveralLevelsDeepHandlesAggregateExceptionErrorStillBubblesToParent ()
881 var continuationRan = false;
882 AggregateException e = null;
883 var testTask = new Task (() =>
885 var child1 = new Task (() =>
887 var child2 = new Task (() =>
889 throw new InvalidOperationException();
890 }, TaskCreationOptions.AttachedToParent);
891 child2.RunSynchronously ();
892 }, TaskCreationOptions.AttachedToParent);
894 child1.RunSynchronously();
895 e = child1.Exception;
896 child1.Exception.Handle (ex => true);
898 var onErrorTask = testTask.ContinueWith (x => continuationRan = true, TaskContinuationOptions.OnlyOnFaulted);
899 testTask.RunSynchronously ();
900 onErrorTask.Wait (100);
901 Assert.IsNotNull (e);
902 Assert.IsTrue (continuationRan);
906 public void AlreadyCompletedChildTaskShouldRunContinuationImmediately ()
908 string result = "Failed";
909 var testTask = new Task (() =>
911 var child = new Task<string> (() =>
914 }, TaskCreationOptions.AttachedToParent);
915 child.RunSynchronously ();
916 child.ContinueWith (x => { Thread.Sleep (50); result = x.Result; }, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.NotOnFaulted);
918 testTask.RunSynchronously ();
920 Assert.AreEqual ("Success", result);
924 public void InlineNotTrashingParentRelationship ()
926 bool r1 = false, r2 = false;
927 var t = new Task (() => {
928 new Task (() => { r1 = true; }, TaskCreationOptions.AttachedToParent).RunSynchronously ();
929 Task.Factory.StartNew (() => { Thread.Sleep (100); r2 = true; }, TaskCreationOptions.AttachedToParent);
931 t.RunSynchronously ();
939 public void Delay_Invalid ()
943 } catch (ArgumentOutOfRangeException) {
948 public void Delay_Start ()
950 var t = Task.Delay (5000);
953 } catch (InvalidOperationException) {
958 public void Delay_Simple ()
960 var t = Task.Delay (300);
961 Assert.IsTrue (TaskStatus.WaitingForActivation == t.Status || TaskStatus.Running == t.Status, "#1");
962 Assert.IsTrue (t.Wait (400), "#2");
966 public void Delay_Cancelled ()
968 var cancelation = new CancellationTokenSource ();
970 var t = Task.Delay (5000, cancelation.Token);
971 Assert.IsTrue (TaskStatus.WaitingForActivation == t.Status || TaskStatus.Running == t.Status, "#1");
972 cancelation.Cancel ();
976 } catch (AggregateException) {
977 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#3");
980 cancelation = new CancellationTokenSource ();
981 t = Task.Delay (Timeout.Infinite, cancelation.Token);
982 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
983 cancelation.Cancel ();
987 } catch (AggregateException) {
988 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#13");
993 public void WaitAny_WithNull ()
1001 Task.WaitAny (tasks);
1003 } catch (ArgumentException) {
1008 public void WhenAll_WithNull ()
1011 Task.FromResult (2),
1016 Task.WhenAll (tasks);
1018 } catch (ArgumentException) {
1023 Task.WhenAll (tasks);
1025 } catch (ArgumentException) {
1030 public void WhenAll_Start ()
1032 Task[] tasks = new[] {
1033 Task.FromResult (2),
1036 var t = Task.WhenAll (tasks);
1037 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1042 } catch (InvalidOperationException) {
1046 new Task (delegate { }),
1049 t = Task.WhenAll (tasks);
1050 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1054 Assert.Fail ("#12");
1055 } catch (InvalidOperationException) {
1060 public void WhenAll_Cancelled ()
1062 var cancelation = new CancellationTokenSource ();
1063 var tasks = new Task[] {
1064 new Task (delegate { }),
1065 new Task (delegate { }, cancelation.Token)
1068 cancelation.Cancel ();
1070 var t = Task.WhenAll (tasks);
1071 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1075 Assert.IsTrue (t.Wait (1000), "#2");
1076 Assert.Fail ("#2a");
1077 } catch (AggregateException e) {
1078 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1083 public void WhenAll_Faulted ()
1085 var tcs = new TaskCompletionSource<object> ();
1086 tcs.SetException (new ApplicationException ());
1088 var tcs2 = new TaskCompletionSource<object> ();
1089 tcs2.SetException (new InvalidTimeZoneException ());
1091 var cancelation = new CancellationTokenSource ();
1092 var tasks = new Task[] {
1093 new Task (delegate { }),
1094 new Task (delegate { }, cancelation.Token),
1099 cancelation.Cancel ();
1101 var t = Task.WhenAll (tasks);
1102 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1106 Assert.IsTrue (t.Wait (1000), "#2");
1107 Assert.Fail ("#2a");
1108 } catch (AggregateException e) {
1109 Assert.IsInstanceOfType (typeof (ApplicationException), e.InnerException, "#3");
1110 Assert.IsInstanceOfType (typeof (InvalidTimeZoneException), e.InnerExceptions[1], "#4");
1115 public void WhenAll ()
1117 var t1 = new Task (delegate { });
1118 var t2 = new Task (delegate { t1.Start (); });
1120 var tasks = new Task[] {
1125 var t = Task.WhenAll (tasks);
1126 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1129 Assert.IsTrue (t.Wait (1000), "#2");
1133 public void WhenAllResult_WithNull ()
1136 Task.FromResult (2),
1141 Task.WhenAll<int> (tasks);
1143 } catch (ArgumentException) {
1148 Task.WhenAll<int> (tasks);
1150 } catch (ArgumentException) {
1155 public void WhenAllResult_Cancelled ()
1157 var cancelation = new CancellationTokenSource ();
1158 var tasks = new [] {
1159 new Task<int> (delegate { return 9; }),
1160 new Task<int> (delegate { return 1; }, cancelation.Token)
1163 cancelation.Cancel ();
1165 var t = Task.WhenAll (tasks);
1166 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1170 Assert.IsTrue (t.Wait (1000), "#2");
1171 Assert.Fail ("#2a");
1172 } catch (AggregateException e) {
1173 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1179 } catch (AggregateException) {
1184 public void WhenAllResult ()
1186 var t1 = new Task<string> (delegate { return "a"; });
1187 var t2 = new Task<string> (delegate { t1.Start (); return "b"; });
1189 var tasks = new [] {
1194 var t = Task.WhenAll<string> (tasks);
1195 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1198 Assert.IsTrue (t.Wait (1000), "#2");
1199 Assert.AreEqual (2, t.Result.Length, "#3");
1200 Assert.AreEqual ("a", t.Result[0], "#3a");
1201 Assert.AreEqual ("b", t.Result[1], "#3b");
1205 public void WhenAllResult_Completed ()
1208 Task.FromResult (1),
1212 var t = Task.WhenAll<int> (tasks);
1213 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1214 Assert.AreEqual (2, t.Result.Length, "#2");
1215 Assert.AreEqual (1, t.Result[0], "#2a");
1216 Assert.AreEqual (2, t.Result[1], "#2b");
1220 public void WhenAny_WithNull ()
1222 var tasks = new Task[] {
1223 Task.FromResult (2),
1228 Task.WhenAny (tasks);
1230 } catch (ArgumentException) {
1235 Task.WhenAny (tasks);
1237 } catch (ArgumentException) {
1241 Task.WhenAny (new Task[0]);
1243 } catch (ArgumentException) {
1248 public void WhenAny_Start ()
1250 Task[] tasks = new[] {
1251 Task.FromResult (2),
1254 var t = Task.WhenAny (tasks);
1255 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1260 } catch (InvalidOperationException) {
1264 new Task (delegate { }),
1267 t = Task.WhenAny (tasks);
1268 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1272 Assert.Fail ("#12");
1273 } catch (InvalidOperationException) {
1278 public void WhenAny_Cancelled ()
1280 var cancelation = new CancellationTokenSource ();
1281 var tasks = new Task[] {
1282 new Task (delegate { }),
1283 new Task (delegate { }, cancelation.Token)
1286 cancelation.Cancel ();
1288 var t = Task.WhenAny (tasks);
1289 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1292 Assert.IsTrue (t.Wait (1000), "#2");
1293 Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1297 public void WhenAny_Faulted ()
1299 var tcs = new TaskCompletionSource<object> ();
1300 tcs.SetException (new ApplicationException ());
1302 var tcs2 = new TaskCompletionSource<object> ();
1303 tcs2.SetException (new InvalidTimeZoneException ());
1305 var cancelation = new CancellationTokenSource ();
1306 var tasks = new Task[] {
1307 new Task (delegate { }),
1309 new Task (delegate { }, cancelation.Token),
1313 cancelation.Cancel ();
1315 var t = Task.WhenAny (tasks);
1316 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1319 Assert.IsTrue (t.Wait (1000), "#2");
1320 Assert.IsNull (t.Exception, "#3");
1322 Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1326 public void WhenAny ()
1328 var t1 = new Task (delegate { });
1329 var t2 = new Task (delegate { t1.Start (); });
1331 var tasks = new Task[] {
1336 var t = Task.WhenAny (tasks);
1337 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1340 Assert.IsTrue (t.Wait (1000), "#2");
1341 Assert.IsNotNull (t.Result, "#3");
1345 public void WhenAnyResult_WithNull ()
1347 var tasks = new [] {
1348 Task.FromResult (2),
1353 Task.WhenAny<int> (tasks);
1355 } catch (ArgumentException) {
1360 Task.WhenAny<int> (tasks);
1362 } catch (ArgumentException) {
1366 Task.WhenAny<short> (new Task<short>[0]);
1368 } catch (ArgumentException) {
1373 public void WhenAnyResult_Start ()
1376 Task.FromResult (2),
1379 var t = Task.WhenAny<int> (tasks);
1380 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1385 } catch (InvalidOperationException) {
1389 new Task<int> (delegate { return 55; }),
1392 t = Task.WhenAny<int> (tasks);
1393 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1397 Assert.Fail ("#12");
1398 } catch (InvalidOperationException) {
1403 public void WhenAnyResult_Cancelled ()
1405 var cancelation = new CancellationTokenSource ();
1406 var tasks = new [] {
1407 new Task<double> (delegate { return 1.1; }),
1408 new Task<double> (delegate { return -4.4; }, cancelation.Token)
1411 cancelation.Cancel ();
1413 var t = Task.WhenAny<double> (tasks);
1414 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1417 Assert.IsTrue (t.Wait (1000), "#2");
1418 Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1422 public void WhenAnyResult_Faulted ()
1424 var tcs = new TaskCompletionSource<object> ();
1425 tcs.SetException (new ApplicationException ());
1427 var tcs2 = new TaskCompletionSource<object> ();
1428 tcs2.SetException (new InvalidTimeZoneException ());
1430 var cancelation = new CancellationTokenSource ();
1431 var tasks = new Task<object>[] {
1432 new Task<object> (delegate { return null; }),
1434 new Task<object> (delegate { return ""; }, cancelation.Token),
1438 cancelation.Cancel ();
1440 var t = Task.WhenAny<object> (tasks);
1441 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1444 Assert.IsTrue (t.Wait (1000), "#2");
1445 Assert.IsNull (t.Exception, "#3");
1447 Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1451 public void WhenAnyResult ()
1453 var t1 = new Task<byte> (delegate { return 3; });
1454 var t2 = new Task<byte> (delegate { t1.Start (); return 2; });
1456 var tasks = new [] {
1461 var t = Task.WhenAny<byte> (tasks);
1462 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1465 Assert.IsTrue (t.Wait (1000), "#2");
1466 Assert.IsTrue (t.Result.Result > 1, "#3");
1470 public void ContinueWith_StateValue ()
1472 var t = Task.Factory.StartNew (l => {
1473 Assert.AreEqual (1, l, "a-1");
1476 var c = t.ContinueWith ((a, b) => {
1477 Assert.AreEqual (t, a, "c-1");
1478 Assert.AreEqual (2, b, "c-2");
1481 var d = t.ContinueWith ((a, b) => {
1482 Assert.AreEqual (t, a, "d-1");
1483 Assert.AreEqual (3, b, "d-2");
1487 Assert.IsTrue (d.Wait (1000), "#1");
1489 Assert.AreEqual (1, t.AsyncState, "#2");
1490 Assert.AreEqual (2, c.AsyncState, "#3");
1491 Assert.AreEqual (3, d.AsyncState, "#4");
1495 public void ContinueWith_StateValueGeneric ()
1497 var t = Task<int>.Factory.StartNew (l => {
1498 Assert.AreEqual (1, l, "a-1");
1502 var c = t.ContinueWith ((a, b) => {
1503 Assert.AreEqual (t, a, "c-1");
1504 Assert.AreEqual (2, b, "c-2");
1508 var d = t.ContinueWith ((a, b) => {
1509 Assert.AreEqual (t, a, "d-1");
1510 Assert.AreEqual (3, b, "d-2");
1514 Assert.IsTrue (d.Wait (1000), "#1");
1516 Assert.AreEqual (1, t.AsyncState, "#2");
1517 Assert.AreEqual (80, t.Result, "#2r");
1518 Assert.AreEqual (2, c.AsyncState, "#3");
1519 Assert.AreEqual ("c", c.Result, "#3r");
1520 Assert.AreEqual (3, d.AsyncState, "#4");
1521 Assert.AreEqual ('d', d.Result, "#3r");
1525 public void FromResult ()
1527 var t = Task.FromResult<object> (null);
1528 Assert.IsTrue (t.IsCompleted, "#1");
1529 Assert.AreEqual (null, t.Result, "#2");
1535 public void LongRunning ()
1539 var t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; });
1541 Assert.IsTrue (t.Wait (100));
1542 Assert.IsTrue ((bool)is_tp, "#1");
1543 Assert.IsTrue ((bool)is_bg, "#2");
1547 t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; }, TaskCreationOptions.LongRunning);
1550 Assert.IsTrue (t.Wait (100));
1551 Assert.IsFalse ((bool) is_tp, "#11");
1552 Assert.IsTrue ((bool) is_bg, "#12");
1556 public void Run_ArgumentCheck ()
1559 Task.Run (null as Action);
1561 } catch (ArgumentNullException) {
1568 var t = Task.Run (delegate { });
1569 Assert.AreEqual (TaskCreationOptions.DenyChildAttach, t.CreationOptions, "#1");
1574 public void Run_Cancel ()
1576 var t = Task.Run (() => 1, new CancellationToken (true));
1580 } catch (AggregateException) {
1583 Assert.IsTrue (t.IsCanceled, "#2");
1587 public void Run_ExistingTask ()
1589 var t = new Task<int> (() => 5);
1590 var t2 = Task.Run (() => { t.Start (); return t; });
1592 Assert.IsTrue (t2.Wait (1000), "#1");
1593 Assert.AreEqual (5, t2.Result, "#2");