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.AreEqual (TaskStatus.WaitingForActivation, 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.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
972 cancelation.Cancel ();
976 } catch (AggregateException) {
977 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#3");
982 public void WaitAny_WithNull ()
990 Task.WaitAny (tasks);
992 } catch (ArgumentException) {
997 public void WhenAll_WithNull ()
1000 Task.FromResult (2),
1005 Task.WhenAll (tasks);
1007 } catch (ArgumentException) {
1012 Task.WhenAll (tasks);
1014 } catch (ArgumentException) {
1019 public void WhenAll_Start ()
1021 Task[] tasks = new[] {
1022 Task.FromResult (2),
1025 var t = Task.WhenAll (tasks);
1026 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1031 } catch (InvalidOperationException) {
1035 new Task (delegate { }),
1038 t = Task.WhenAll (tasks);
1039 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1043 Assert.Fail ("#12");
1044 } catch (InvalidOperationException) {
1049 public void WhenAll_Cancelled ()
1051 var cancelation = new CancellationTokenSource ();
1052 var tasks = new Task[] {
1053 new Task (delegate { }),
1054 new Task (delegate { }, cancelation.Token)
1057 cancelation.Cancel ();
1059 var t = Task.WhenAll (tasks);
1060 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1064 Assert.IsTrue (t.Wait (1000), "#2");
1065 Assert.Fail ("#2a");
1066 } catch (AggregateException e) {
1067 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1072 public void WhenAll_Faulted ()
1074 var tcs = new TaskCompletionSource<object> ();
1075 tcs.SetException (new ApplicationException ());
1077 var tcs2 = new TaskCompletionSource<object> ();
1078 tcs2.SetException (new InvalidTimeZoneException ());
1080 var cancelation = new CancellationTokenSource ();
1081 var tasks = new Task[] {
1082 new Task (delegate { }),
1083 new Task (delegate { }, cancelation.Token),
1088 cancelation.Cancel ();
1090 var t = Task.WhenAll (tasks);
1091 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1095 Assert.IsTrue (t.Wait (1000), "#2");
1096 Assert.Fail ("#2a");
1097 } catch (AggregateException e) {
1098 Assert.IsInstanceOfType (typeof (ApplicationException), e.InnerException, "#3");
1099 Assert.IsInstanceOfType (typeof (InvalidTimeZoneException), e.InnerExceptions[1], "#4");
1104 public void WhenAll ()
1106 var t1 = new Task (delegate { });
1107 var t2 = new Task (delegate { t1.Start (); });
1109 var tasks = new Task[] {
1114 var t = Task.WhenAll (tasks);
1115 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1118 Assert.IsTrue (t.Wait (1000), "#2");
1122 public void WhenAllResult_WithNull ()
1125 Task.FromResult (2),
1130 Task.WhenAll<int> (tasks);
1132 } catch (ArgumentException) {
1137 Task.WhenAll<int> (tasks);
1139 } catch (ArgumentException) {
1144 public void WhenAllResult_Cancelled ()
1146 var cancelation = new CancellationTokenSource ();
1147 var tasks = new [] {
1148 new Task<int> (delegate { return 9; }),
1149 new Task<int> (delegate { return 1; }, cancelation.Token)
1152 cancelation.Cancel ();
1154 var t = Task.WhenAll (tasks);
1155 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1159 Assert.IsTrue (t.Wait (1000), "#2");
1160 Assert.Fail ("#2a");
1161 } catch (AggregateException e) {
1162 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1168 } catch (AggregateException) {
1173 public void WhenAllResult ()
1175 var t1 = new Task<string> (delegate { return "a"; });
1176 var t2 = new Task<string> (delegate { t1.Start (); return "b"; });
1178 var tasks = new [] {
1183 var t = Task.WhenAll<string> (tasks);
1184 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1187 Assert.IsTrue (t.Wait (1000), "#2");
1188 Assert.AreEqual (2, t.Result.Length, "#3");
1189 Assert.AreEqual ("a", t.Result[0], "#3a");
1190 Assert.AreEqual ("b", t.Result[1], "#3b");
1194 public void WhenAllResult_Completed ()
1197 Task.FromResult (1),
1201 var t = Task.WhenAll<int> (tasks);
1202 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1203 Assert.AreEqual (2, t.Result.Length, "#2");
1204 Assert.AreEqual (1, t.Result[0], "#2a");
1205 Assert.AreEqual (2, t.Result[1], "#2b");
1209 public void WhenAny_WithNull ()
1211 var tasks = new Task[] {
1212 Task.FromResult (2),
1217 Task.WhenAny (tasks);
1219 } catch (ArgumentException) {
1224 Task.WhenAny (tasks);
1226 } catch (ArgumentException) {
1230 Task.WhenAny (new Task[0]);
1232 } catch (ArgumentException) {
1237 public void WhenAny_Start ()
1239 Task[] tasks = new[] {
1240 Task.FromResult (2),
1243 var t = Task.WhenAny (tasks);
1244 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1249 } catch (InvalidOperationException) {
1253 new Task (delegate { }),
1256 t = Task.WhenAny (tasks);
1257 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1261 Assert.Fail ("#12");
1262 } catch (InvalidOperationException) {
1267 public void WhenAny_Cancelled ()
1269 var cancelation = new CancellationTokenSource ();
1270 var tasks = new Task[] {
1271 new Task (delegate { }),
1272 new Task (delegate { }, cancelation.Token)
1275 cancelation.Cancel ();
1277 var t = Task.WhenAny (tasks);
1278 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1281 Assert.IsTrue (t.Wait (1000), "#2");
1282 Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1286 public void WhenAny_Faulted ()
1288 var tcs = new TaskCompletionSource<object> ();
1289 tcs.SetException (new ApplicationException ());
1291 var tcs2 = new TaskCompletionSource<object> ();
1292 tcs2.SetException (new InvalidTimeZoneException ());
1294 var cancelation = new CancellationTokenSource ();
1295 var tasks = new Task[] {
1296 new Task (delegate { }),
1298 new Task (delegate { }, cancelation.Token),
1302 cancelation.Cancel ();
1304 var t = Task.WhenAny (tasks);
1305 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1308 Assert.IsTrue (t.Wait (1000), "#2");
1309 Assert.IsNull (t.Exception, "#3");
1311 Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1315 public void WhenAny ()
1317 var t1 = new Task (delegate { });
1318 var t2 = new Task (delegate { t1.Start (); });
1320 var tasks = new Task[] {
1325 var t = Task.WhenAny (tasks);
1326 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1329 Assert.IsTrue (t.Wait (1000), "#2");
1330 Assert.IsNotNull (t.Result, "#3");
1334 public void WhenAnyResult_WithNull ()
1336 var tasks = new [] {
1337 Task.FromResult (2),
1342 Task.WhenAny<int> (tasks);
1344 } catch (ArgumentException) {
1349 Task.WhenAny<int> (tasks);
1351 } catch (ArgumentException) {
1355 Task.WhenAny<short> (new Task<short>[0]);
1357 } catch (ArgumentException) {
1362 public void WhenAnyResult_Start ()
1365 Task.FromResult (2),
1368 var t = Task.WhenAny<int> (tasks);
1369 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1374 } catch (InvalidOperationException) {
1378 new Task<int> (delegate { return 55; }),
1381 t = Task.WhenAny<int> (tasks);
1382 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1386 Assert.Fail ("#12");
1387 } catch (InvalidOperationException) {
1392 public void WhenAnyResult_Cancelled ()
1394 var cancelation = new CancellationTokenSource ();
1395 var tasks = new [] {
1396 new Task<double> (delegate { return 1.1; }),
1397 new Task<double> (delegate { return -4.4; }, cancelation.Token)
1400 cancelation.Cancel ();
1402 var t = Task.WhenAny<double> (tasks);
1403 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1406 Assert.IsTrue (t.Wait (1000), "#2");
1407 Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1411 public void WhenAnyResult_Faulted ()
1413 var tcs = new TaskCompletionSource<object> ();
1414 tcs.SetException (new ApplicationException ());
1416 var tcs2 = new TaskCompletionSource<object> ();
1417 tcs2.SetException (new InvalidTimeZoneException ());
1419 var cancelation = new CancellationTokenSource ();
1420 var tasks = new Task<object>[] {
1421 new Task<object> (delegate { return null; }),
1423 new Task<object> (delegate { return ""; }, cancelation.Token),
1427 cancelation.Cancel ();
1429 var t = Task.WhenAny<object> (tasks);
1430 Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1433 Assert.IsTrue (t.Wait (1000), "#2");
1434 Assert.IsNull (t.Exception, "#3");
1436 Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1440 public void WhenAnyResult ()
1442 var t1 = new Task<byte> (delegate { return 3; });
1443 var t2 = new Task<byte> (delegate { t1.Start (); return 2; });
1445 var tasks = new [] {
1450 var t = Task.WhenAny<byte> (tasks);
1451 Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1454 Assert.IsTrue (t.Wait (1000), "#2");
1455 Assert.IsTrue (t.Result.Result > 1, "#3");
1459 public void ContinueWith_StateValue ()
1461 var t = Task.Factory.StartNew (l => {
1462 Assert.AreEqual (1, l, "a-1");
1465 var c = t.ContinueWith ((a, b) => {
1466 Assert.AreEqual (t, a, "c-1");
1467 Assert.AreEqual (2, b, "c-2");
1470 var d = t.ContinueWith ((a, b) => {
1471 Assert.AreEqual (t, a, "d-1");
1472 Assert.AreEqual (3, b, "d-2");
1476 Assert.IsTrue (d.Wait (1000), "#1");
1478 Assert.AreEqual (1, t.AsyncState, "#2");
1479 Assert.AreEqual (2, c.AsyncState, "#3");
1480 Assert.AreEqual (3, d.AsyncState, "#4");
1484 public void ContinueWith_StateValueGeneric ()
1486 var t = Task<int>.Factory.StartNew (l => {
1487 Assert.AreEqual (1, l, "a-1");
1491 var c = t.ContinueWith ((a, b) => {
1492 Assert.AreEqual (t, a, "c-1");
1493 Assert.AreEqual (2, b, "c-2");
1497 var d = t.ContinueWith ((a, b) => {
1498 Assert.AreEqual (t, a, "d-1");
1499 Assert.AreEqual (3, b, "d-2");
1503 Assert.IsTrue (d.Wait (1000), "#1");
1505 Assert.AreEqual (1, t.AsyncState, "#2");
1506 Assert.AreEqual (80, t.Result, "#2r");
1507 Assert.AreEqual (2, c.AsyncState, "#3");
1508 Assert.AreEqual ("c", c.Result, "#3r");
1509 Assert.AreEqual (3, d.AsyncState, "#4");
1510 Assert.AreEqual ('d', d.Result, "#3r");
1514 public void FromResult ()
1516 var t = Task.FromResult<object> (null);
1517 Assert.IsTrue (t.IsCompleted, "#1");
1518 Assert.AreEqual (null, t.Result, "#2");
1524 public void LongRunning ()
1528 var t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; });
1530 Assert.IsTrue (t.Wait (100));
1531 Assert.IsTrue ((bool)is_tp, "#1");
1532 Assert.IsTrue ((bool)is_bg, "#2");
1536 t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; }, TaskCreationOptions.LongRunning);
1539 Assert.IsTrue (t.Wait (100));
1540 Assert.IsFalse ((bool) is_tp, "#11");
1541 Assert.IsTrue ((bool) is_bg, "#12");
1545 public void Run_ArgumentCheck ()
1548 Task.Run (null as Action);
1550 } catch (ArgumentNullException) {
1557 var t = Task.Run (delegate { });
1558 Assert.AreEqual (TaskCreationOptions.DenyChildAttach, t.CreationOptions, "#1");
1563 public void Run_Cancel ()
1565 var t = Task.Run (() => 1, new CancellationToken (true));
1569 } catch (AggregateException) {
1572 Assert.IsTrue (t.IsCanceled, "#2");
1576 public void Run_ExistingTask ()
1578 var t = new Task<int> (() => 5);
1579 var t2 = Task.Run (() => { t.Start (); return t; });
1581 Assert.IsTrue (t2.Wait (1000), "#1");
1582 Assert.AreEqual (5, t2.Result, "#2");