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