Merge pull request #274 from iainlane/master
[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.AreEqual (TaskStatus.WaitingForActivation, 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.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
972                         cancelation.Cancel ();
973                         try {
974                                 t.Wait (100);
975                                 Assert.Fail ("#2");
976                         } catch (AggregateException) {
977                                 Assert.AreEqual (TaskStatus.Canceled, t.Status, "#3");
978                         }
979                 }
980
981                 [Test]
982                 public void WaitAny_WithNull ()
983                 {
984                         var tasks = new [] {
985                                 Task.FromResult (2),
986                                 null
987                         };
988
989                         try {
990                                 Task.WaitAny (tasks);
991                                 Assert.Fail ();
992                         } catch (ArgumentException) {
993                         }
994                 }
995
996                 [Test]
997                 public void WhenAll_WithNull ()
998                 {
999                         var tasks = new[] {
1000                                 Task.FromResult (2),
1001                                 null
1002                         };
1003
1004                         try {
1005                                 Task.WhenAll (tasks);
1006                                 Assert.Fail ("#1");
1007                         } catch (ArgumentException) {
1008                         }
1009
1010                         tasks = null;
1011                         try {
1012                                 Task.WhenAll (tasks);
1013                                 Assert.Fail ("#2");
1014                         } catch (ArgumentException) {
1015                         }
1016                 }
1017
1018                 [Test]
1019                 public void WhenAll_Start ()
1020                 {
1021                         Task[] tasks = new[] {
1022                                 Task.FromResult (2),
1023                         };
1024
1025                         var t = Task.WhenAll (tasks);
1026                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1027
1028                         try {
1029                                 t.Start ();
1030                                 Assert.Fail ("#2");
1031                         } catch (InvalidOperationException) {
1032                         }
1033
1034                         tasks = new [] {
1035                                 new Task (delegate { }),
1036                         };
1037
1038                         t = Task.WhenAll (tasks);
1039                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1040
1041                         try {
1042                                 t.Start ();
1043                                 Assert.Fail ("#12");
1044                         } catch (InvalidOperationException) {
1045                         }
1046                 }
1047
1048                 [Test]
1049                 public void WhenAll_Cancelled ()
1050                 {
1051                         var cancelation = new CancellationTokenSource ();
1052                         var tasks = new Task[] {
1053                                 new Task (delegate { }),
1054                                 new Task (delegate { }, cancelation.Token)
1055                         };
1056
1057                         cancelation.Cancel ();
1058
1059                         var t = Task.WhenAll (tasks);
1060                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1061                         tasks[0].Start ();
1062
1063                         try {
1064                                 Assert.IsTrue (t.Wait (1000), "#2");
1065                                 Assert.Fail ("#2a");
1066                         } catch (AggregateException e) {
1067                                 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1068                         }
1069                 }
1070
1071                 [Test]
1072                 public void WhenAll_Faulted ()
1073                 {
1074                         var tcs = new TaskCompletionSource<object> ();
1075                         tcs.SetException (new ApplicationException ());
1076
1077                         var tcs2 = new TaskCompletionSource<object> ();
1078                         tcs2.SetException (new InvalidTimeZoneException ());
1079
1080                         var cancelation = new CancellationTokenSource ();
1081                         var tasks = new Task[] {
1082                                 new Task (delegate { }),
1083                                 new Task (delegate { }, cancelation.Token),
1084                                 tcs.Task,
1085                                 tcs2.Task
1086                         };
1087
1088                         cancelation.Cancel ();
1089
1090                         var t = Task.WhenAll (tasks);
1091                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1092                         tasks[0].Start ();
1093
1094                         try {
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");
1100                         }
1101                 }
1102
1103                 [Test]
1104                 public void WhenAll ()
1105                 {
1106                         var t1 = new Task (delegate { });
1107                         var t2 = new Task (delegate { t1.Start (); });
1108
1109                         var tasks = new Task[] {
1110                                 t1,
1111                                 t2,
1112                         };
1113
1114                         var t = Task.WhenAll (tasks);
1115                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1116                         t2.Start ();
1117
1118                         Assert.IsTrue (t.Wait (1000), "#2");
1119                 }
1120
1121                 [Test]
1122                 public void WhenAllResult_WithNull ()
1123                 {
1124                         var tasks = new[] {
1125                                 Task.FromResult (2),
1126                                 null
1127                         };
1128
1129                         try {
1130                                 Task.WhenAll<int> (tasks);
1131                                 Assert.Fail ("#1");
1132                         } catch (ArgumentException) {
1133                         }
1134
1135                         tasks = null;
1136                         try {
1137                                 Task.WhenAll<int> (tasks);
1138                                 Assert.Fail ("#2");
1139                         } catch (ArgumentException) {
1140                         }
1141                 }
1142
1143                 [Test]
1144                 public void WhenAllResult_Cancelled ()
1145                 {
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)
1150                         };
1151
1152                         cancelation.Cancel ();
1153
1154                         var t = Task.WhenAll (tasks);
1155                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1156                         tasks[0].Start ();
1157
1158                         try {
1159                                 Assert.IsTrue (t.Wait (1000), "#2");
1160                                 Assert.Fail ("#2a");
1161                         } catch (AggregateException e) {
1162                                 Assert.IsInstanceOfType (typeof (TaskCanceledException), e.InnerException, "#3");
1163                         }
1164
1165                         try {
1166                                 var r = t.Result;
1167                                 Assert.Fail ("#4");
1168                         } catch (AggregateException) {
1169                         }
1170                 }
1171
1172                 [Test]
1173                 public void WhenAllResult ()
1174                 {
1175                         var t1 = new Task<string> (delegate { return "a"; });
1176                         var t2 = new Task<string> (delegate { t1.Start (); return "b"; });
1177
1178                         var tasks = new [] {
1179                                 t1,
1180                                 t2,
1181                         };
1182
1183                         var t = Task.WhenAll<string> (tasks);
1184                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1185                         t2.Start ();
1186
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");
1191                 }
1192
1193                 [Test]
1194                 public void WhenAllResult_Completed ()
1195                 {
1196                         var tasks = new[] {
1197                                 Task.FromResult (1),
1198                                 Task.FromResult (2)
1199                         };
1200
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");
1206                 }
1207
1208                 [Test]
1209                 public void WhenAny_WithNull ()
1210                 {
1211                         var tasks = new Task[] {
1212                                 Task.FromResult (2),
1213                                 null
1214                         };
1215
1216                         try {
1217                                 Task.WhenAny (tasks);
1218                                 Assert.Fail ("#1");
1219                         } catch (ArgumentException) {
1220                         }
1221
1222                         tasks = null;
1223                         try {
1224                                 Task.WhenAny (tasks);
1225                                 Assert.Fail ("#2");
1226                         } catch (ArgumentException) {
1227                         }
1228
1229                         try {
1230                                 Task.WhenAny (new Task[0]);
1231                                 Assert.Fail ("#3");
1232                         } catch (ArgumentException) {
1233                         }
1234                 }
1235
1236                 [Test]
1237                 public void WhenAny_Start ()
1238                 {
1239                         Task[] tasks = new[] {
1240                                 Task.FromResult (2),
1241                         };
1242
1243                         var t = Task.WhenAny (tasks);
1244                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1245
1246                         try {
1247                                 t.Start ();
1248                                 Assert.Fail ("#2");
1249                         } catch (InvalidOperationException) {
1250                         }
1251
1252                         tasks = new[] {
1253                                 new Task (delegate { }),
1254                         };
1255
1256                         t = Task.WhenAny (tasks);
1257                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1258
1259                         try {
1260                                 t.Start ();
1261                                 Assert.Fail ("#12");
1262                         } catch (InvalidOperationException) {
1263                         }
1264                 }
1265
1266                 [Test]
1267                 public void WhenAny_Cancelled ()
1268                 {
1269                         var cancelation = new CancellationTokenSource ();
1270                         var tasks = new Task[] {
1271                                 new Task (delegate { }),
1272                                 new Task (delegate { }, cancelation.Token)
1273                         };
1274
1275                         cancelation.Cancel ();
1276
1277                         var t = Task.WhenAny (tasks);
1278                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1279                         tasks[0].Start ();
1280
1281                         Assert.IsTrue (t.Wait (1000), "#2");
1282                         Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1283                 }
1284
1285                 [Test]
1286                 public void WhenAny_Faulted ()
1287                 {
1288                         var tcs = new TaskCompletionSource<object> ();
1289                         tcs.SetException (new ApplicationException ());
1290
1291                         var tcs2 = new TaskCompletionSource<object> ();
1292                         tcs2.SetException (new InvalidTimeZoneException ());
1293
1294                         var cancelation = new CancellationTokenSource ();
1295                         var tasks = new Task[] {
1296                                 new Task (delegate { }),
1297                                 tcs.Task,
1298                                 new Task (delegate { }, cancelation.Token),
1299                                 tcs2.Task
1300                         };
1301
1302                         cancelation.Cancel ();
1303
1304                         var t = Task.WhenAny (tasks);
1305                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1306                         tasks[0].Start ();
1307
1308                         Assert.IsTrue (t.Wait (1000), "#2");
1309                         Assert.IsNull (t.Exception, "#3");
1310
1311                         Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1312                 }
1313
1314                 [Test]
1315                 public void WhenAny ()
1316                 {
1317                         var t1 = new Task (delegate { });
1318                         var t2 = new Task (delegate { t1.Start (); });
1319
1320                         var tasks = new Task[] {
1321                                 t1,
1322                                 t2,
1323                         };
1324
1325                         var t = Task.WhenAny (tasks);
1326                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1327                         t2.Start ();
1328
1329                         Assert.IsTrue (t.Wait (1000), "#2");
1330                         Assert.IsNotNull (t.Result, "#3");
1331                 }
1332
1333                 [Test]
1334                 public void WhenAnyResult_WithNull ()
1335                 {
1336                         var tasks = new [] {
1337                                 Task.FromResult (2),
1338                                 null
1339                         };
1340
1341                         try {
1342                                 Task.WhenAny<int> (tasks);
1343                                 Assert.Fail ("#1");
1344                         } catch (ArgumentException) {
1345                         }
1346
1347                         tasks = null;
1348                         try {
1349                                 Task.WhenAny<int> (tasks);
1350                                 Assert.Fail ("#2");
1351                         } catch (ArgumentException) {
1352                         }
1353
1354                         try {
1355                                 Task.WhenAny<short> (new Task<short>[0]);
1356                                 Assert.Fail ("#3");
1357                         } catch (ArgumentException) {
1358                         }
1359                 }
1360
1361                 [Test]
1362                 public void WhenAnyResult_Start ()
1363                 {
1364                         var tasks = new[] {
1365                                 Task.FromResult (2),
1366                         };
1367
1368                         var t = Task.WhenAny<int> (tasks);
1369                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1370
1371                         try {
1372                                 t.Start ();
1373                                 Assert.Fail ("#2");
1374                         } catch (InvalidOperationException) {
1375                         }
1376
1377                         tasks = new[] {
1378                                 new Task<int> (delegate { return 55; }),
1379                         };
1380
1381                         t = Task.WhenAny<int> (tasks);
1382                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#11");
1383
1384                         try {
1385                                 t.Start ();
1386                                 Assert.Fail ("#12");
1387                         } catch (InvalidOperationException) {
1388                         }
1389                 }
1390
1391                 [Test]
1392                 public void WhenAnyResult_Cancelled ()
1393                 {
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)
1398                         };
1399
1400                         cancelation.Cancel ();
1401
1402                         var t = Task.WhenAny<double> (tasks);
1403                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1404                         tasks[0].Start ();
1405
1406                         Assert.IsTrue (t.Wait (1000), "#2");
1407                         Assert.AreEqual (TaskStatus.Canceled, t.Result.Status, "#3");
1408                 }
1409
1410                 [Test]
1411                 public void WhenAnyResult_Faulted ()
1412                 {
1413                         var tcs = new TaskCompletionSource<object> ();
1414                         tcs.SetException (new ApplicationException ());
1415
1416                         var tcs2 = new TaskCompletionSource<object> ();
1417                         tcs2.SetException (new InvalidTimeZoneException ());
1418
1419                         var cancelation = new CancellationTokenSource ();
1420                         var tasks = new Task<object>[] {
1421                                 new Task<object> (delegate { return null; }),
1422                                 tcs.Task,
1423                                 new Task<object> (delegate { return ""; }, cancelation.Token),
1424                                 tcs2.Task
1425                         };
1426
1427                         cancelation.Cancel ();
1428
1429                         var t = Task.WhenAny<object> (tasks);
1430                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#1");
1431                         tasks[0].Start ();
1432
1433                         Assert.IsTrue (t.Wait (1000), "#2");
1434                         Assert.IsNull (t.Exception, "#3");
1435
1436                         Assert.IsInstanceOfType (typeof (ApplicationException), t.Result.Exception.InnerException, "#4");
1437                 }
1438
1439                 [Test]
1440                 public void WhenAnyResult ()
1441                 {
1442                         var t1 = new Task<byte> (delegate { return 3; });
1443                         var t2 = new Task<byte> (delegate { t1.Start (); return 2; });
1444
1445                         var tasks = new [] {
1446                                 t1,
1447                                 t2,
1448                         };
1449
1450                         var t = Task.WhenAny<byte> (tasks);
1451                         Assert.AreEqual (TaskStatus.WaitingForActivation, t.Status, "#1");
1452                         t2.Start ();
1453
1454                         Assert.IsTrue (t.Wait (1000), "#2");
1455                         Assert.IsTrue (t.Result.Result > 1, "#3");
1456                 }
1457
1458                 [Test]
1459                 public void ContinueWith_StateValue ()
1460                 {
1461                         var t = Task.Factory.StartNew (l => {
1462                                 Assert.AreEqual (1, l, "a-1");
1463                         }, 1);
1464
1465                         var c = t.ContinueWith ((a, b) => {
1466                                 Assert.AreEqual (t, a, "c-1");
1467                                 Assert.AreEqual (2, b, "c-2");
1468                         }, 2);
1469
1470                         var d = t.ContinueWith ((a, b) => {
1471                                 Assert.AreEqual (t, a, "d-1");
1472                                 Assert.AreEqual (3, b, "d-2");
1473                                 return 77;
1474                         }, 3);
1475
1476                         Assert.IsTrue (d.Wait (1000), "#1");
1477
1478                         Assert.AreEqual (1, t.AsyncState, "#2");
1479                         Assert.AreEqual (2, c.AsyncState, "#3");
1480                         Assert.AreEqual (3, d.AsyncState, "#4");
1481                 }
1482
1483                 [Test]
1484                 public void ContinueWith_StateValueGeneric ()
1485                 {
1486                         var t = Task<int>.Factory.StartNew (l => {
1487                                 Assert.AreEqual (1, l, "a-1");
1488                                 return 80;
1489                         }, 1);
1490
1491                         var c = t.ContinueWith ((a, b) => {
1492                                 Assert.AreEqual (t, a, "c-1");
1493                                 Assert.AreEqual (2, b, "c-2");
1494                                 return "c";
1495                         }, 2);
1496
1497                         var d = t.ContinueWith ((a, b) => {
1498                                 Assert.AreEqual (t, a, "d-1");
1499                                 Assert.AreEqual (3, b, "d-2");
1500                                 return 'd';
1501                         }, 3);
1502
1503                         Assert.IsTrue (d.Wait (1000), "#1");
1504
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");
1511                 }
1512
1513                 [Test]
1514                 public void FromResult ()
1515                 {
1516                         var t = Task.FromResult<object> (null);
1517                         Assert.IsTrue (t.IsCompleted, "#1");
1518                         Assert.AreEqual (null, t.Result, "#2");
1519                         t.Dispose ();
1520                         t.Dispose ();
1521                 }
1522
1523                 [Test]
1524                 public void LongRunning ()
1525                 {
1526                         bool? is_tp = null;
1527                         bool? is_bg = null;
1528                         var t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; });
1529                         t.Start ();
1530                         Assert.IsTrue (t.Wait (100));
1531                         Assert.IsTrue ((bool)is_tp, "#1");
1532                         Assert.IsTrue ((bool)is_bg, "#2");
1533
1534                         is_tp = null;
1535                         is_bg = null;
1536                         t = new Task (() => { is_tp = Thread.CurrentThread.IsThreadPoolThread; is_bg = Thread.CurrentThread.IsBackground; }, TaskCreationOptions.LongRunning);
1537                         t.Start ();
1538
1539                         Assert.IsTrue (t.Wait (100));
1540                         Assert.IsFalse ((bool) is_tp, "#11");
1541                         Assert.IsTrue ((bool) is_bg, "#12");
1542                 }
1543
1544                 [Test]
1545                 public void Run_ArgumentCheck ()
1546                 {
1547                         try {
1548                                 Task.Run (null as Action);
1549                                 Assert.Fail ("#1");
1550                         } catch (ArgumentNullException) {
1551                         }
1552                 }
1553
1554                 [Test]
1555                 public void Run ()
1556                 {
1557                         var t = Task.Run (delegate { });
1558                         Assert.AreEqual (TaskCreationOptions.DenyChildAttach, t.CreationOptions, "#1");
1559                         t.Wait ();
1560                 }
1561
1562                 [Test]
1563                 public void Run_Cancel ()
1564                 {
1565                         var t = Task.Run (() => 1, new CancellationToken (true));
1566                         try {
1567                                 var r = t.Result;
1568                                 Assert.Fail ("#1");
1569                         } catch (AggregateException) {
1570                         }
1571
1572                         Assert.IsTrue (t.IsCanceled, "#2");
1573                 }
1574
1575                 [Test]
1576                 public void Run_ExistingTask ()
1577                 {
1578                         var t = new Task<int> (() => 5);
1579                         var t2 = Task.Run (() => { t.Start (); return t; });
1580
1581                         Assert.IsTrue (t2.Wait (1000), "#1");
1582                         Assert.AreEqual (5, t2.Result, "#2");
1583                 }
1584 #endif
1585         }
1586 }
1587 #endif