Bump test timeout
[mono.git] / mcs / class / corlib / Test / System.Threading.Tasks / TaskTest.cs
1 //
2 // TaskTest.cs
3 //
4 // Copyright (c) 2008 Jérémie "Garuma" Laval
5 //
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:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
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
22 // THE SOFTWARE.
23 //
24 //
25
26 #if NET_4_0
27
28 using System;
29 using System.Threading;
30 using System.Threading.Tasks;
31
32 using NUnit.Framework;
33
34 namespace MonoTests.System.Threading.Tasks
35 {
36         [TestFixture]
37         public class TaskTests
38         {
39                 Task[] tasks;
40                 const int max = 6;
41                 
42                 [SetUp]
43                 public void Setup()
44                 {
45                         tasks = new Task[max];                  
46                 }
47                 
48                 void InitWithDelegate(Action action)
49                 {
50                         for (int i = 0; i < max; i++) {
51                                 tasks[i] = Task.Factory.StartNew(action);
52                         }
53                 }
54                 
55                 [Test]
56                 public void WaitAnyTest()
57                 {
58                         ParallelTestHelper.Repeat (delegate {
59                                 int flag = 0;
60                                 int finished = 0;
61                                 
62                                 InitWithDelegate(delegate {
63                                         int times = Interlocked.Exchange (ref flag, 1);
64                                         if (times == 1) {
65                                                 SpinWait sw = new SpinWait ();
66                                                 while (finished == 0) sw.SpinOnce ();
67                                         } else {
68                                                 Interlocked.Increment (ref finished);
69                                         }
70                                 });
71                                 
72                                 int index = Task.WaitAny(tasks, 1000);
73                                 
74                                 Assert.AreNotEqual (-1, index, "#3");
75                                 Assert.AreEqual (1, flag, "#1");
76                                 Assert.AreEqual (1, finished, "#2");
77                         });
78                 }
79
80                 [Test]
81                 public void WaitAny_Empty ()
82                 {
83                         Assert.AreEqual (-1, Task.WaitAny (new Task[0]));
84                 }
85
86                 [Test]
87                 public void WaitAny_Zero ()
88                 {
89                         Assert.AreEqual (-1, Task.WaitAny (new[] { new Task (delegate { })}, 0), "#1");
90                         Assert.AreEqual (-1, Task.WaitAny (new[] { new Task (delegate { }) }, 20), "#1");
91                 }
92
93                 [Test]
94                 public void WaitAny_Cancelled ()
95                 {
96                         var cancelation = new CancellationTokenSource ();
97                         var tasks = new Task[] {
98                                 new Task (delegate { }),
99                                 new Task (delegate { }, cancelation.Token)
100                         };
101
102                         cancelation.Cancel ();
103
104                         Assert.AreEqual (1, Task.WaitAny (tasks, 1000), "#1");
105                         Assert.IsTrue (tasks[1].IsCompleted, "#2");
106                         Assert.IsTrue (tasks[1].IsCanceled, "#3");
107                 }
108
109                 [Test]
110                 public void WaitAny_CancelledWithoutExecution ()
111                 {
112                         var cancelation = new CancellationTokenSource ();
113                         var tasks = new Task[] {
114                                 new Task (delegate { }),
115                                 new Task (delegate { })
116                         };
117
118                         int res = 0;
119                         var mre = new ManualResetEventSlim (false);
120                         ThreadPool.QueueUserWorkItem (delegate {
121                                 res = Task.WaitAny (tasks, 20);
122                                 mre.Set ();
123                         });
124
125                         cancelation.Cancel ();
126                         Assert.IsTrue (mre.Wait (1000), "#1");
127                         Assert.AreEqual (-1, res);
128                 }
129
130                 [Test]
131                 public void WaitAny_OneException ()
132                 {
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 (); })
137                         };
138
139                         Assert.AreEqual (1, Task.WaitAny (tasks, 1000), "#1");
140                         Assert.IsFalse (tasks[0].IsCompleted, "#2");
141                         Assert.IsTrue (tasks[1].IsFaulted, "#3");
142
143                         mre.Set ();
144                 }
145
146                 [Test]
147                 public void WaitAny_SingleCanceled ()
148                 {
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 }));
152                 }
153
154                 public void WaitAny_ManyExceptions ()
155                 {
156                         CountdownEvent cde = new CountdownEvent (3);
157                         var tasks = new [] {
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 (); } })
161                         };
162
163                         Assert.IsTrue (cde.Wait (1000), "#1");
164
165                         try {
166                                 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#2");
167                         } catch (AggregateException e) {
168                                 Assert.AreEqual (3, e.InnerExceptions.Count, "#3");
169                         }
170                 }
171
172                 [Test]
173                 public void WaitAny_ManyCanceled ()
174                 {
175                         var cancellation = new CancellationToken (true);
176                         var tasks = new[] {
177                                 Task.Factory.StartNew (delegate { }, cancellation),
178                                 Task.Factory.StartNew (delegate { }, cancellation),
179                                 Task.Factory.StartNew (delegate { }, cancellation)
180                         };
181
182                         try {
183                                 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#1");
184                         } catch (AggregateException e) {
185                                 Assert.AreEqual (3, e.InnerExceptions.Count, "#2");
186                         }
187                 }
188                 
189                 [Test]
190                 public void WaitAllTest ()
191                 {
192                         ParallelTestHelper.Repeat (delegate {
193                                 int achieved = 0;
194                                 InitWithDelegate(delegate { Interlocked.Increment(ref achieved); });
195                                 Task.WaitAll(tasks);
196                                 Assert.AreEqual(max, achieved, "#1");
197                         });
198                 }
199
200                 [Test]
201                 public void WaitAll_ManyTasks ()
202                 {
203                         for (int r = 0; r < 2000; ++r) {
204                                 var tasks = new Task[60];
205
206                                 for (int i = 0; i < tasks.Length; i++) {
207                                         tasks[i] = Task.Factory.StartNew (delegate { Thread.Sleep (0); });
208                                 }
209
210                                 Assert.IsTrue (Task.WaitAll (tasks, 2000));
211                         }
212                 }
213
214                 [Test]
215                 public void WaitAll_Zero ()
216                 {
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");
219                 }
220
221                 [Test]
222                 public void WaitAll_WithExceptions ()
223                 {
224                         InitWithDelegate (delegate { throw new ApplicationException (); });
225
226                         try {
227                                 Task.WaitAll (tasks);
228                                 Assert.Fail ("#1");
229                         } catch (AggregateException e) {
230                                 Assert.AreEqual (6, e.InnerExceptions.Count, "#2");
231                         }
232
233                         Assert.IsNotNull (tasks[0].Exception, "#3");
234                 }
235
236                 [Test]
237                 public void WaitAll_TimeoutWithExceptionsAfter ()
238                 {
239                         CountdownEvent cde = new CountdownEvent (2);
240                         var mre = new ManualResetEvent (false);
241                         var tasks = new[] {
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 (); } })
245                         };
246
247                         Assert.IsTrue (cde.Wait (1000), "#1");
248                         Assert.IsFalse (Task.WaitAll (tasks, 1000), "#2");
249
250                         mre.Set ();
251
252                         try {
253                                 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#3");
254                                 Assert.Fail ("#4");
255                         } catch (AggregateException e) {
256                                 Assert.AreEqual (2, e.InnerExceptions.Count, "#5");
257                         }
258                 }
259
260                 [Test]
261                 public void WaitAll_TimeoutWithExceptionsBefore ()
262                 {
263                         CountdownEvent cde = new CountdownEvent (2);
264                         var mre = new ManualResetEvent (false);
265                         var tasks = new[] {
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 (); })
269                         };
270
271                         Assert.IsTrue (cde.Wait (1000), "#1");
272                         Assert.IsFalse (Task.WaitAll (tasks, 1000), "#2");
273
274                         mre.Set ();
275
276                         try {
277                                 Assert.IsTrue (Task.WaitAll (tasks, 1000), "#3");
278                                 Assert.Fail ("#4");
279                         } catch (AggregateException e) {
280                                 Assert.AreEqual (2, e.InnerExceptions.Count, "#5");
281                         }
282                 }
283
284                 [Test]
285                 public void WaitAll_Cancelled ()
286                 {
287                         var cancelation = new CancellationTokenSource ();
288                         var tasks = new Task[] {
289                                 new Task (delegate { cancelation.Cancel (); }),
290                                 new Task (delegate { }, cancelation.Token)
291                         };
292
293                         tasks[0].Start ();
294
295                         try {
296                                 Task.WaitAll (tasks);
297                                 Assert.Fail ("#1");
298                         } catch (AggregateException e) {
299                                 var inner = (TaskCanceledException) e.InnerException;
300                                 Assert.AreEqual (tasks[1], inner.Task, "#2");
301                         }
302
303                         Assert.IsTrue (tasks[0].IsCompleted, "#3");
304                         Assert.IsTrue (tasks[1].IsCanceled, "#4");
305                 }
306
307                 [Test]
308                 public void WaitAllExceptionThenCancelled ()
309                 {
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)
314                         };
315
316                         tasks[0].Start ();
317
318                         try {
319                                 Task.WaitAll (tasks);
320                                 Assert.Fail ("#1");
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");
325                         }
326
327                         Assert.IsTrue (tasks[0].IsCompleted, "#4");
328                         Assert.IsTrue (tasks[1].IsCanceled, "#5");
329                 }
330
331                 [Test]
332                 public void WaitAll_StartedUnderWait ()
333                 {
334                         var task1 = new Task (delegate { });
335
336                         ThreadPool.QueueUserWorkItem (delegate {
337                                 // Sleep little to let task to start and hit internal wait
338                                 Thread.Sleep (20);
339                                 task1.Start ();
340                         });
341
342                         Assert.IsTrue (Task.WaitAll (new [] { task1 }, 1000), "#1");
343                 }
344
345                 [Test]
346                 public void CancelBeforeStart ()
347                 {
348                         var src = new CancellationTokenSource ();
349
350                         Task t = new Task (delegate { }, src.Token);
351                         src.Cancel ();
352                         Assert.AreEqual (TaskStatus.Canceled, t.Status, "#1");
353
354                         try {
355                                 t.Start ();
356                                 Assert.Fail ("#2");
357                         } catch (InvalidOperationException) {
358                         }
359                 }
360
361                 [Test]
362                 public void Wait_CancelledTask ()
363                 {
364                         var src = new CancellationTokenSource ();
365
366                         Task t = new Task (delegate { }, src.Token);
367                         src.Cancel ();
368
369                         try {
370                                 t.Wait (1000);
371                                 Assert.Fail ("#1");
372                         } catch (AggregateException e) {
373                                 var details = (TaskCanceledException) e.InnerException;
374                                 Assert.AreEqual (t, details.Task, "#1e");
375                         }
376
377                         try {
378                                 t.Wait ();
379                                 Assert.Fail ("#2");
380                         } catch (AggregateException e) {
381                                 var details = (TaskCanceledException) e.InnerException;
382                                 Assert.AreEqual (t, details.Task, "#2e");
383                                 Assert.IsNull (details.Task.Exception, "#2e2");
384                         }
385                 }
386
387                 [Test, ExpectedException (typeof (InvalidOperationException))]
388                 public void CreationWhileInitiallyCanceled ()
389                 {
390                         var token = new CancellationToken (true);
391                         var task = new Task (() => { }, token);
392                         Assert.AreEqual (TaskStatus.Canceled, task.Status);
393                         task.Start ();
394                 }
395
396                 [Test]
397                 public void ContinueWithInvalidArguments ()
398                 {
399                         var task = new Task (() => { });
400                         try {
401                                 task.ContinueWith (null);
402                                 Assert.Fail ("#1");
403                         } catch (ArgumentException) {
404                         }
405
406                         try {
407                                 task.ContinueWith (delegate { }, null);
408                                 Assert.Fail ("#2");
409                         } catch (ArgumentException) {
410                         }
411
412                         try {
413                                 task.ContinueWith (delegate { }, TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.NotOnCanceled);
414                                 Assert.Fail ("#3");
415                         } catch (ArgumentException) {
416                         }
417
418                         try {
419                                 task.ContinueWith (delegate { }, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion);
420                                 Assert.Fail ("#4");
421                         } catch (ArgumentException) {
422                         }
423                 }
424
425                 [Test]
426                 public void ContinueWithOnAnyTestCase()
427                 {
428                         ParallelTestHelper.Repeat (delegate {
429                                 bool result = false;
430                                 
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");
438                         });
439                 }
440                 
441                 [Test]
442                 public void ContinueWithOnCompletedSuccessfullyTestCase()
443                 {
444                         ParallelTestHelper.Repeat (delegate {
445                                 bool result = false;
446                                 
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");
451                                 
452                                 Assert.IsNull(cont.Exception, "#1");
453                                 Assert.IsNotNull(cont, "#2");
454                                 Assert.IsTrue(result, "#3");
455                         });
456                 }
457                 
458                 [Test]
459                 public void ContinueWithOnAbortedTestCase()
460                 {
461                         bool result = false;
462                         bool taskResult = false;
463
464                         CancellationTokenSource src = new CancellationTokenSource ();
465                         Task t = new Task (delegate { taskResult = true; }, src.Token);
466
467                         Task cont = t.ContinueWith (delegate { result = true; },
468                                 TaskContinuationOptions.OnlyOnCanceled | TaskContinuationOptions.ExecuteSynchronously);
469
470                         src.Cancel ();
471
472                         Assert.AreEqual (TaskStatus.Canceled, t.Status, "#1a");
473                         Assert.IsTrue (cont.IsCompleted, "#1b");
474                         Assert.IsTrue (result, "#1c");
475
476                         try {
477                                 t.Start ();
478                                 Assert.Fail ("#2");
479                         } catch (InvalidOperationException) {
480                         }
481
482                         Assert.IsTrue (cont.Wait (1000), "#3");
483
484                         Assert.IsFalse (taskResult, "#4");
485
486                         Assert.IsNull (cont.Exception, "#5");
487                         Assert.AreEqual (TaskStatus.RanToCompletion, cont.Status, "#6");
488                 }
489                 
490                 [Test]
491                 public void ContinueWithOnFailedTestCase()
492                 {
493                         ParallelTestHelper.Repeat (delegate {
494                                 bool result = false;
495                                 
496                                 Task t = Task.Factory.StartNew(delegate { throw new Exception("foo"); });       
497                                 Task cont = t.ContinueWith(delegate { result = true; }, TaskContinuationOptions.OnlyOnFaulted);
498                         
499                                 Assert.IsTrue (cont.Wait(1000), "#0");
500                                 Assert.IsNotNull (t.Exception, "#1");
501                                 Assert.IsNotNull (cont, "#2");
502                                 Assert.IsTrue (result, "#3");
503                         });
504                 }
505
506                 [Test]
507                 public void ContinueWithWithStart ()
508                 {
509                         Task t = new Task<int> (() => 1);
510                         t = t.ContinueWith (l => { });
511                         try {
512                                 t.Start ();
513                                 Assert.Fail ();
514                         } catch (InvalidOperationException) {
515                         }
516                 }
517
518                 [Test]
519                 public void ContinueWithChildren ()
520                 {
521                         ParallelTestHelper.Repeat (delegate {
522                             bool result = false;
523
524                             var t = Task.Factory.StartNew (() => Task.Factory.StartNew (() => {}, TaskCreationOptions.AttachedToParent));
525
526                                 var mre = new ManualResetEvent (false);
527                             t.ContinueWith (l => {
528                                         result = true;
529                                         mre.Set ();
530                                 });
531
532                                 Assert.IsTrue (mre.WaitOne (1000), "#1");
533                             Assert.IsTrue (result, "#2");
534                         }, 2);
535                 }
536
537                 [Test]
538                 public void ContinueWithDifferentOptionsAreCanceledTest ()
539                 {
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);
545
546                         mre.Set ();
547                         contSuccess.Wait (100);
548
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);
555                 }
556
557                 [Test]
558                 public void MultipleTasks()
559                 {
560                         ParallelTestHelper.Repeat (delegate {
561                                 bool r1 = false, r2 = false, r3 = false;
562                                 
563                                 Task t1 = Task.Factory.StartNew(delegate {
564                                         r1 = true;
565                                 });
566                                 Task t2 = Task.Factory.StartNew(delegate {
567                                         r2 = true;
568                                 });
569                                 Task t3 = Task.Factory.StartNew(delegate {
570                                         r3 = true;
571                                 });
572                                 
573                                 t1.Wait(2000);
574                                 t2.Wait(2000);
575                                 t3.Wait(2000);
576                                 
577                                 Assert.IsTrue(r1, "#1");
578                                 Assert.IsTrue(r2, "#2");
579                                 Assert.IsTrue(r3, "#3");
580                         }, 100);
581                 }
582                 
583                 [Test]
584                 public void WaitChildTestCase()
585                 {
586                         ParallelTestHelper.Repeat (delegate {
587                                 bool r1 = false, r2 = false, r3 = false;
588                                 var mre = new ManualResetEventSlim (false);
589                                 var mreStart = new ManualResetEventSlim (false);
590                                 
591                                 Task t = Task.Factory.StartNew(delegate {
592                                         Task.Factory.StartNew(delegate {
593                                                 mre.Wait (300);
594                                                 r1 = true;
595                                         }, TaskCreationOptions.AttachedToParent);
596                                         Task.Factory.StartNew(delegate {
597                                                 r2 = true;
598                                         }, TaskCreationOptions.AttachedToParent);
599                                         Task.Factory.StartNew(delegate {
600                                                 r3 = true;
601                                         }, TaskCreationOptions.AttachedToParent);
602                                         mreStart.Set ();
603                                 });
604                                 
605                                 mreStart.Wait (300);
606                                 Assert.IsFalse (t.Wait (10), "#0a");
607                                 mre.Set ();
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");
613                         }, 10);
614                 }
615
616                 [Test]
617                 public void WaitChildWithContinuationAttachedTest ()
618                 {
619                         bool result = false;
620                         var task = new Task(() =>
621                         {
622                                 Task.Factory.StartNew(() =>     {
623                                         Thread.Sleep (200);
624                                 }, TaskCreationOptions.AttachedToParent).ContinueWith(t => {
625                                         Thread.Sleep (200);
626                                         result = true;
627                                 }, TaskContinuationOptions.AttachedToParent);
628                         });
629                         task.Start();
630                         task.Wait();
631                         Assert.IsTrue (result);
632                 }
633
634                 [Test]
635                 public void WaitChildWithContinuationNotAttachedTest ()
636                 {
637                         var task = new Task(() =>
638                         {
639                                 Task.Factory.StartNew(() =>     {
640                                         Thread.Sleep (200);
641                                 }, TaskCreationOptions.AttachedToParent).ContinueWith(t => {
642                                         Thread.Sleep (3000);
643                                 });
644                         });
645                         task.Start();
646                         Assert.IsTrue (task.Wait(400));
647                 }
648
649                 [Test]
650                 public void WaitChildWithNesting ()
651                 {
652                         var result = false;
653                         var t = Task.Factory.StartNew (() => {
654                                 Task.Factory.StartNew (() => {
655                                         Task.Factory.StartNew (() => {
656                                                 Thread.Sleep (500);
657                                                 result = true;
658                                         }, TaskCreationOptions.AttachedToParent);
659                                 }, TaskCreationOptions.AttachedToParent);
660                         });
661                         t.Wait ();
662                         Assert.IsTrue (result);
663                 }
664
665                 [Test]
666                 public void DoubleWaitTest ()
667                 {
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);
673
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 (); });
677
678                                 cntd.Wait (2000);
679                                 cntd.Reset ();
680                                 evt.Set ();
681                                 cntd.Wait (2000);
682                                 Assert.IsTrue (r1);
683                                 Assert.IsTrue (r2);
684                         }, 5);
685                 }
686
687                 [Test]
688                 public void DoubleTimeoutedWaitTest ()
689                 {
690                         var evt = new ManualResetEventSlim ();
691                         var t = new Task (delegate { });
692                         var cntd = new CountdownEvent (2);
693
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 (); });
697
698                         cntd.Wait (2000);
699                         Assert.IsTrue (r1);
700                         Assert.IsTrue (r2);
701                 }
702
703                 [Test]
704                 public void ExecuteSynchronouslyTest ()
705                 {
706                         var val = 0;
707                         Task t = new Task (() => { Thread.Sleep (100); val = 1; });
708                         t.RunSynchronously ();
709
710                         Assert.AreEqual (1, val);
711                 }
712
713                 [Test]
714                 public void RunSynchronouslyArgumentChecks ()
715                 {
716                         Task t = new Task (() => { });
717                         try {
718                                 t.RunSynchronously (null);
719                                 Assert.Fail ("#1");
720                         } catch (ArgumentNullException) {
721                         }
722                 }
723
724                 [Test]
725                 public void RunSynchronouslyWithAttachedChildren ()
726                 {
727                         var result = false;
728                         var t = new Task (() => {
729                                 Task.Factory.StartNew (() => { Thread.Sleep (500); result = true; }, TaskCreationOptions.AttachedToParent);
730                         });
731                         t.RunSynchronously ();
732                         Assert.IsTrue (result);
733                 }
734
735                 [Test]
736                 public void UnobservedExceptionOnFinalizerThreadTest ()
737                 {
738                         bool wasCalled = false;
739                         TaskScheduler.UnobservedTaskException += (o, args) => {
740                                 wasCalled = true;
741                                 args.SetObserved ();
742                         };
743                         var inner = new ApplicationException ();
744                         Task.Factory.StartNew (() => { throw inner; });
745                         Thread.Sleep (1000);
746                         GC.Collect ();
747                         Thread.Sleep (1000);
748                         GC.WaitForPendingFinalizers ();
749
750                         Assert.IsTrue (wasCalled);
751                 }
752
753                 [Test, ExpectedException (typeof (InvalidOperationException))]
754                 public void StartFinishedTaskTest ()
755                 {
756                         var t = Task.Factory.StartNew (delegate () { });
757                         t.Wait ();
758
759                         t.Start ();
760                 }
761
762                 [Test]
763                 public void Start_NullArgument ()
764                 {
765                         var t = Task.Factory.StartNew (delegate () { });
766                         try {
767                                 t.Start (null);
768                                 Assert.Fail ();
769                         } catch (ArgumentNullException) {
770                         }
771                 }
772
773                 [Test, ExpectedException (typeof (InvalidOperationException))]
774                 public void DisposeUnstartedTest ()
775                 {
776                         var t = new Task (() => { });
777                         t.Dispose ();
778                 }
779
780                 [Test]
781                 public void ThrowingUnrelatedCanceledExceptionTest ()
782                 {
783                         Task t = new Task (() => {
784                                 throw new TaskCanceledException ();
785                         });
786
787                         t.RunSynchronously ();
788                         Assert.IsTrue (t.IsFaulted);
789                         Assert.IsFalse (t.IsCanceled);
790                 }
791
792                 [Test]
793                 public void CanceledContinuationExecuteSynchronouslyTest ()
794                 {
795                         var source = new CancellationTokenSource();
796                         var token = source.Token;
797                         var evt = new ManualResetEventSlim ();
798                         bool result = false;
799                         bool thrown = false;
800
801                         var task = Task.Factory.StartNew (() => evt.Wait (100));
802                         var cont = task.ContinueWith (t => result = true, token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
803
804                         source.Cancel();
805                         evt.Set ();
806                         task.Wait (100);
807                         try {
808                                 cont.Wait (100);
809                         } catch (Exception ex) {
810                                 thrown = true;
811                         }
812
813                         Assert.IsTrue (task.IsCompleted);
814                         Assert.IsTrue (cont.IsCanceled);
815                         Assert.IsFalse (result);
816                         Assert.IsTrue (thrown);
817                 }
818
819                 [Test]
820                 public void WhenChildTaskErrorIsThrownParentTaskShouldBeFaulted ()
821                 {
822                         Task innerTask = null;
823                         var testTask = new Task (() =>
824                         {
825                                 innerTask = new Task (() => 
826                                 {
827                                         throw new InvalidOperationException ();
828                                 }, TaskCreationOptions.AttachedToParent);
829                                 innerTask.RunSynchronously ();
830                         });
831                         testTask.RunSynchronously ();
832
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);
839                 }
840                 
841                 [Test]
842                 public void WhenChildTaskErrorIsThrownOnlyOnFaultedContinuationShouldExecute ()
843                 {
844                         var continuationRan = false;
845                         var testTask = new Task (() =>
846                         {
847                                 var task = new Task (() => 
848                                 {
849                                         throw new InvalidOperationException();
850                                 }, TaskCreationOptions.AttachedToParent);
851                                 task.RunSynchronously ();
852                         });
853                         var onErrorTask = testTask.ContinueWith (x => continuationRan = true, TaskContinuationOptions.OnlyOnFaulted);
854                         testTask.RunSynchronously ();
855                         onErrorTask.Wait (100);
856                         Assert.IsTrue (continuationRan);
857                 }
858                 
859                 [Test]
860                 public void WhenChildTaskErrorIsThrownNotOnFaultedContinuationShouldNotBeExecuted ()
861                 {
862                         var continuationRan = false;
863                         var testTask = new Task (() =>
864                         {
865                                 var task = new Task (() => 
866                                 {
867                                         throw new InvalidOperationException();
868                                 }, TaskCreationOptions.AttachedToParent);
869                                 task.RunSynchronously();
870                         });
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);
876                 }       
877                 
878                 [Test]
879                 public void WhenChildTaskSeveralLevelsDeepHandlesAggregateExceptionErrorStillBubblesToParent ()
880                 {
881                         var continuationRan = false;
882                         AggregateException e = null;
883                         var testTask = new Task (() =>
884                         {
885                                 var child1 = new Task (() =>
886                                 {
887                                         var child2 = new Task (() => 
888                                         {
889                                                 throw new InvalidOperationException();
890                                         }, TaskCreationOptions.AttachedToParent);
891                                         child2.RunSynchronously ();
892                                 }, TaskCreationOptions.AttachedToParent);
893                                 
894                                 child1.RunSynchronously();
895                                 e = child1.Exception;
896                                 child1.Exception.Handle (ex => true);
897                         });
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);
903                 }
904                 
905                 [Test]
906                 public void AlreadyCompletedChildTaskShouldRunContinuationImmediately ()
907                 {
908                         string result = "Failed";
909                         var testTask = new Task (() => 
910                         {
911                                 var child = new Task<string> (() =>
912                                 {
913                                         return "Success";
914                                 }, TaskCreationOptions.AttachedToParent);
915                                 child.RunSynchronously ();
916                                 child.ContinueWith (x => { Thread.Sleep (50); result = x.Result; }, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.NotOnFaulted);
917                         });
918                         testTask.RunSynchronously ();
919
920                         Assert.AreEqual ("Success", result);
921                 }
922
923                 [Test]
924                 public void InlineNotTrashingParentRelationship ()
925                 {
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);
930                     });
931                         t.RunSynchronously ();
932
933                         Assert.IsTrue (r1);
934                         Assert.IsTrue (r2);
935                 }
936
937 #if NET_4_5
938                 [Test]
939                 public void Delay_Invalid ()
940                 {
941                         try {
942                                 Task.Delay (-100);
943                         } catch (ArgumentOutOfRangeException) {
944                         }
945                 }
946
947                 [Test]
948                 public void Delay_Start ()
949                 {
950                         var t = Task.Delay (5000);
951                         try {
952                                 t.Start ();
953                         } catch (InvalidOperationException) {
954                         }
955                 }
956
957                 [Test]
958                 public void Delay_Simple ()
959                 {
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");
963                 }
964
965                 [Test]
966                 public void Delay_Cancelled ()
967                 {
968                         var cancelation = new CancellationTokenSource ();
969
970                         var t = Task.Delay (5000, cancelation.Token);
971                         Assert.IsTrue (TaskStatus.WaitingForActivation == t.Status || TaskStatus.Running == t.Status, "#1");
972                         cancelation.Cancel ();
973                         try {
974                                 t.Wait (1000);
975                                 Assert.Fail ("#2");
976                         } catch (AggregateException) {
977                                 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#3");
978                         }
979                         
980                         cancelation = new CancellationTokenSource ();
981                         t = Task.Delay (Timeout.Infinite, cancelation.Token);
982                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
983                         cancelation.Cancel ();
984                         try {
985                                 t.Wait (1000);
986                                 Assert.Fail ("#12");
987                         } catch (AggregateException) {
988                                 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#13");
989                         }
990                 }
991
992                 [Test]
993                 public void WaitAny_WithNull ()
994                 {
995                         var tasks = new [] {
996                                 Task.FromResult (2),
997                                 null
998                         };
999
1000                         try {
1001                                 Task.WaitAny (tasks);
1002                                 Assert.Fail ();
1003                         } catch (ArgumentException) {
1004                         }
1005                 }
1006
1007                 [Test]
1008                 public void WhenAll_WithNull ()
1009                 {
1010                         var tasks = new[] {
1011                                 Task.FromResult (2),
1012                                 null
1013                         };
1014
1015                         try {
1016                                 Task.WhenAll (tasks);
1017                                 Assert.Fail ("#1");
1018                         } catch (ArgumentException) {
1019                         }
1020
1021                         tasks = null;
1022                         try {
1023                                 Task.WhenAll (tasks);
1024                                 Assert.Fail ("#2");
1025                         } catch (ArgumentException) {
1026                         }
1027                 }
1028
1029                 [Test]
1030                 public void WhenAll_Start ()
1031                 {
1032                         Task[] tasks = new[] {
1033                                 Task.FromResult (2),
1034                         };
1035
1036                         var t = Task.WhenAll (tasks);
1037                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1038
1039                         try {
1040                                 t.Start ();
1041                                 Assert.Fail ("#2");
1042                         } catch (InvalidOperationException) {
1043                         }
1044
1045                         tasks = new [] {
1046                                 new Task (delegate { }),
1047                         };
1048
1049                         t = Task.WhenAll (tasks);
1050                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1051
1052                         try {
1053                                 t.Start ();
1054                                 Assert.Fail ("#12");
1055                         } catch (InvalidOperationException) {
1056                         }
1057                 }
1058
1059                 [Test]
1060                 public void WhenAll_Cancelled ()
1061                 {
1062                         var cancelation = new CancellationTokenSource ();
1063                         var tasks = new Task[] {
1064                                 new Task (delegate { }),
1065                                 new Task (delegate { }, cancelation.Token)
1066                         };
1067
1068                         cancelation.Cancel ();
1069
1070                         var t = Task.WhenAll (tasks);
1071                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1072                         tasks[0].Start ();
1073
1074                         try {
1075                                 Assert.IsTrue (t.Wait (1000), "#2");
1076                                 Assert.Fail ("#2a");
1077                         } catch (AggregateException e) {
1078                                 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1079                         }
1080                 }
1081
1082                 [Test]
1083                 public void WhenAll_Faulted ()
1084                 {
1085                         var tcs = new TaskCompletionSource<object> ();
1086                         tcs.SetException (new ApplicationException ());
1087
1088                         var tcs2 = new TaskCompletionSource<object> ();
1089                         tcs2.SetException (new InvalidTimeZoneException ());
1090
1091                         var cancelation = new CancellationTokenSource ();
1092                         var tasks = new Task[] {
1093                                 new Task (delegate { }),
1094                                 new Task (delegate { }, cancelation.Token),
1095                                 tcs.Task,
1096                                 tcs2.Task
1097                         };
1098
1099                         cancelation.Cancel ();
1100
1101                         var t = Task.WhenAll (tasks);
1102                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1103                         tasks[0].Start ();
1104
1105                         try {
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");
1111                         }
1112                 }
1113
1114                 [Test]
1115                 public void WhenAll ()
1116                 {
1117                         var t1 = new Task (delegate { });
1118                         var t2 = new Task (delegate { t1.Start (); });
1119
1120                         var tasks = new Task[] {
1121                                 t1,
1122                                 t2,
1123                         };
1124
1125                         var t = Task.WhenAll (tasks);
1126                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1127                         t2.Start ();
1128
1129                         Assert.IsTrue (t.Wait (1000), "#2");
1130                 }
1131
1132                 [Test]
1133                 public void WhenAllResult_WithNull ()
1134                 {
1135                         var tasks = new[] {
1136                                 Task.FromResult (2),
1137                                 null
1138                         };
1139
1140                         try {
1141                                 Task.WhenAll<int> (tasks);
1142                                 Assert.Fail ("#1");
1143                         } catch (ArgumentException) {
1144                         }
1145
1146                         tasks = null;
1147                         try {
1148                                 Task.WhenAll<int> (tasks);
1149                                 Assert.Fail ("#2");
1150                         } catch (ArgumentException) {
1151                         }
1152                 }
1153
1154                 [Test]
1155                 public void WhenAllResult_Cancelled ()
1156                 {
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)
1161                         };
1162
1163                         cancelation.Cancel ();
1164
1165                         var t = Task.WhenAll (tasks);
1166                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1167                         tasks[0].Start ();
1168
1169                         try {
1170                                 Assert.IsTrue (t.Wait (1000), "#2");
1171                                 Assert.Fail ("#2a");
1172                         } catch (AggregateException e) {
1173                                 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1174                         }
1175
1176                         try {
1177                                 var r = t.Result;
1178                                 Assert.Fail ("#4");
1179                         } catch (AggregateException) {
1180                         }
1181                 }
1182
1183                 [Test]
1184                 public void WhenAllResult ()
1185                 {
1186                         var t1 = new Task<string> (delegate { return "a"; });
1187                         var t2 = new Task<string> (delegate { t1.Start (); return "b"; });
1188
1189                         var tasks = new [] {
1190                                 t1,
1191                                 t2,
1192                         };
1193
1194                         var t = Task.WhenAll<string> (tasks);
1195                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1196                         t2.Start ();
1197
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");
1202                 }
1203
1204                 [Test]
1205                 public void WhenAllResult_Completed ()
1206                 {
1207                         var tasks = new[] {
1208                                 Task.FromResult (1),
1209                                 Task.FromResult (2)
1210                         };
1211
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");
1217                 }
1218
1219                 [Test]
1220                 public void WhenAny_WithNull ()
1221                 {
1222                         var tasks = new Task[] {
1223                                 Task.FromResult (2),
1224                                 null
1225                         };
1226
1227                         try {
1228                                 Task.WhenAny (tasks);
1229                                 Assert.Fail ("#1");
1230                         } catch (ArgumentException) {
1231                         }
1232
1233                         tasks = null;
1234                         try {
1235                                 Task.WhenAny (tasks);
1236                                 Assert.Fail ("#2");
1237                         } catch (ArgumentException) {
1238                         }
1239
1240                         try {
1241                                 Task.WhenAny (new Task[0]);
1242                                 Assert.Fail ("#3");
1243                         } catch (ArgumentException) {
1244                         }
1245                 }
1246
1247                 [Test]
1248                 public void WhenAny_Start ()
1249                 {
1250                         Task[] tasks = new[] {
1251                                 Task.FromResult (2),
1252                         };
1253
1254                         var t = Task.WhenAny (tasks);
1255                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1256
1257                         try {
1258                                 t.Start ();
1259                                 Assert.Fail ("#2");
1260                         } catch (InvalidOperationException) {
1261                         }
1262
1263                         tasks = new[] {
1264                                 new Task (delegate { }),
1265                         };
1266
1267                         t = Task.WhenAny (tasks);
1268                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1269
1270                         try {
1271                                 t.Start ();
1272                                 Assert.Fail ("#12");
1273                         } catch (InvalidOperationException) {
1274                         }
1275                 }
1276
1277                 [Test]
1278                 public void WhenAny_Cancelled ()
1279                 {
1280                         var cancelation = new CancellationTokenSource ();
1281                         var tasks = new Task[] {
1282                                 new Task (delegate { }),
1283                                 new Task (delegate { }, cancelation.Token)
1284                         };
1285
1286                         cancelation.Cancel ();
1287
1288                         var t = Task.WhenAny (tasks);
1289                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1290                         tasks[0].Start ();
1291
1292                         Assert.IsTrue (t.Wait (1000), "#2");
1293                         Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1294                 }
1295
1296                 [Test]
1297                 public void WhenAny_Faulted ()
1298                 {
1299                         var tcs = new TaskCompletionSource<object> ();
1300                         tcs.SetException (new ApplicationException ());
1301
1302                         var tcs2 = new TaskCompletionSource<object> ();
1303                         tcs2.SetException (new InvalidTimeZoneException ());
1304
1305                         var cancelation = new CancellationTokenSource ();
1306                         var tasks = new Task[] {
1307                                 new Task (delegate { }),
1308                                 tcs.Task,
1309                                 new Task (delegate { }, cancelation.Token),
1310                                 tcs2.Task
1311                         };
1312
1313                         cancelation.Cancel ();
1314
1315                         var t = Task.WhenAny (tasks);
1316                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1317                         tasks[0].Start ();
1318
1319                         Assert.IsTrue (t.Wait (1000), "#2");
1320                         Assert.IsNull (t.Exception, "#3");
1321
1322                         Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1323                 }
1324
1325                 [Test]
1326                 public void WhenAny ()
1327                 {
1328                         var t1 = new Task (delegate { });
1329                         var t2 = new Task (delegate { t1.Start (); });
1330
1331                         var tasks = new Task[] {
1332                                 t1,
1333                                 t2,
1334                         };
1335
1336                         var t = Task.WhenAny (tasks);
1337                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1338                         t2.Start ();
1339
1340                         Assert.IsTrue (t.Wait (1000), "#2");
1341                         Assert.IsNotNull (t.Result, "#3");
1342                 }
1343
1344                 [Test]
1345                 public void WhenAnyResult_WithNull ()
1346                 {
1347                         var tasks = new [] {
1348                                 Task.FromResult (2),
1349                                 null
1350                         };
1351
1352                         try {
1353                                 Task.WhenAny<int> (tasks);
1354                                 Assert.Fail ("#1");
1355                         } catch (ArgumentException) {
1356                         }
1357
1358                         tasks = null;
1359                         try {
1360                                 Task.WhenAny<int> (tasks);
1361                                 Assert.Fail ("#2");
1362                         } catch (ArgumentException) {
1363                         }
1364
1365                         try {
1366                                 Task.WhenAny<short> (new Task<short>[0]);
1367                                 Assert.Fail ("#3");
1368                         } catch (ArgumentException) {
1369                         }
1370                 }
1371
1372                 [Test]
1373                 public void WhenAnyResult_Start ()
1374                 {
1375                         var tasks = new[] {
1376                                 Task.FromResult (2),
1377                         };
1378
1379                         var t = Task.WhenAny<int> (tasks);
1380                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1381
1382                         try {
1383                                 t.Start ();
1384                                 Assert.Fail ("#2");
1385                         } catch (InvalidOperationException) {
1386                         }
1387
1388                         tasks = new[] {
1389                                 new Task<int> (delegate { return 55; }),
1390                         };
1391
1392                         t = Task.WhenAny<int> (tasks);
1393                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1394
1395                         try {
1396                                 t.Start ();
1397                                 Assert.Fail ("#12");
1398                         } catch (InvalidOperationException) {
1399                         }
1400                 }
1401
1402                 [Test]
1403                 public void WhenAnyResult_Cancelled ()
1404                 {
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)
1409                         };
1410
1411                         cancelation.Cancel ();
1412
1413                         var t = Task.WhenAny<double> (tasks);
1414                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1415                         tasks[0].Start ();
1416
1417                         Assert.IsTrue (t.Wait (1000), "#2");
1418                         Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1419                 }
1420
1421                 [Test]
1422                 public void WhenAnyResult_Faulted ()
1423                 {
1424                         var tcs = new TaskCompletionSource<object> ();
1425                         tcs.SetException (new ApplicationException ());
1426
1427                         var tcs2 = new TaskCompletionSource<object> ();
1428                         tcs2.SetException (new InvalidTimeZoneException ());
1429
1430                         var cancelation = new CancellationTokenSource ();
1431                         var tasks = new Task<object>[] {
1432                                 new Task<object> (delegate { return null; }),
1433                                 tcs.Task,
1434                                 new Task<object> (delegate { return ""; }, cancelation.Token),
1435                                 tcs2.Task
1436                         };
1437
1438                         cancelation.Cancel ();
1439
1440                         var t = Task.WhenAny<object> (tasks);
1441                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1442                         tasks[0].Start ();
1443
1444                         Assert.IsTrue (t.Wait (1000), "#2");
1445                         Assert.IsNull (t.Exception, "#3");
1446
1447                         Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1448                 }
1449
1450                 [Test]
1451                 public void WhenAnyResult ()
1452                 {
1453                         var t1 = new Task<byte> (delegate { return 3; });
1454                         var t2 = new Task<byte> (delegate { t1.Start (); return 2; });
1455
1456                         var tasks = new [] {
1457                                 t1,
1458                                 t2,
1459                         };
1460
1461                         var t = Task.WhenAny<byte> (tasks);
1462                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1463                         t2.Start ();
1464
1465                         Assert.IsTrue (t.Wait (1000), "#2");
1466                         Assert.IsTrue (t.Result.Result > 1, "#3");
1467                 }
1468
1469                 [Test]
1470                 public void ContinueWith_StateValue ()
1471                 {
1472                         var t = Task.Factory.StartNew (l => {
1473                                 Assert.AreEqual (1, l, "a-1");
1474                         }, 1);
1475
1476                         var c = t.ContinueWith ((a, b) => {
1477                                 Assert.AreEqual (t, a, "c-1");
1478                                 Assert.AreEqual (2, b, "c-2");
1479                         }, 2);
1480
1481                         var d = t.ContinueWith ((a, b) => {
1482                                 Assert.AreEqual (t, a, "d-1");
1483                                 Assert.AreEqual (3, b, "d-2");
1484                                 return 77;
1485                         }, 3);
1486
1487                         Assert.IsTrue (d.Wait (1000), "#1");
1488
1489                         Assert.AreEqual (1, t.AsyncState, "#2");
1490                         Assert.AreEqual (2, c.AsyncState, "#3");
1491                         Assert.AreEqual (3, d.AsyncState, "#4");
1492                 }
1493
1494                 [Test]
1495                 public void ContinueWith_StateValueGeneric ()
1496                 {
1497                         var t = Task<int>.Factory.StartNew (l => {
1498                                 Assert.AreEqual (1, l, "a-1");
1499                                 return 80;
1500                         }, 1);
1501
1502                         var c = t.ContinueWith ((a, b) => {
1503                                 Assert.AreEqual (t, a, "c-1");
1504                                 Assert.AreEqual (2, b, "c-2");
1505                                 return "c";
1506                         }, 2);
1507
1508                         var d = t.ContinueWith ((a, b) => {
1509                                 Assert.AreEqual (t, a, "d-1");
1510                                 Assert.AreEqual (3, b, "d-2");
1511                                 return 'd';
1512                         }, 3);
1513
1514                         Assert.IsTrue (d.Wait (1000), "#1");
1515
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");
1522                 }
1523
1524                 [Test]
1525                 public void FromResult ()
1526                 {
1527                         var t = Task.FromResult<object> (null);
1528                         Assert.IsTrue (t.IsCompleted, "#1");
1529                         Assert.AreEqual (null, t.Result, "#2");
1530                         t.Dispose ();
1531                         t.Dispose ();
1532                 }
1533
1534                 [Test]
1535                 public void LongRunning ()
1536                 {
1537                         bool? is_tp = null;
1538                         bool? is_bg = null;
1539                         var t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; });
1540                         t.Start ();
1541                         Assert.IsTrue (t.Wait (100));
1542                         Assert.IsTrue ((bool)is_tp, "#1");
1543                         Assert.IsTrue ((bool)is_bg, "#2");
1544
1545                         is_tp = null;
1546                         is_bg = null;
1547                         t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; }, TaskCreationOptions.LongRunning);
1548                         t.Start ();
1549
1550                         Assert.IsTrue (t.Wait (100));
1551                         Assert.IsFalse ((bool) is_tp, "#11");
1552                         Assert.IsTrue ((bool) is_bg, "#12");
1553                 }
1554
1555                 [Test]
1556                 public void Run_ArgumentCheck ()
1557                 {
1558                         try {
1559                                 Task.Run (null as Action);
1560                                 Assert.Fail ("#1");
1561                         } catch (ArgumentNullException) {
1562                         }
1563                 }
1564
1565                 [Test]
1566                 public void Run ()
1567                 {
1568                         var t = Task.Run (delegate { });
1569                         Assert.AreEqual (TaskCreationOptions.DenyChildAttach, t.CreationOptions, "#1");
1570                         t.Wait ();
1571                 }
1572
1573                 [Test]
1574                 public void Run_Cancel ()
1575                 {
1576                         var t = Task.Run (() => 1, new CancellationToken (true));
1577                         try {
1578                                 var r = t.Result;
1579                                 Assert.Fail ("#1");
1580                         } catch (AggregateException) {
1581                         }
1582
1583                         Assert.IsTrue (t.IsCanceled, "#2");
1584                 }
1585
1586                 [Test]
1587                 public void Run_ExistingTask ()
1588                 {
1589                         var t = new Task<int> (() => 5);
1590                         var t2 = Task.Run (() => { t.Start (); return t; });
1591
1592                         Assert.IsTrue (t2.Wait (1000), "#1");
1593                         Assert.AreEqual (5, t2.Result, "#2");
1594                 }
1595 #endif
1596         }
1597 }
1598 #endif