Add unit test for AggregateException.GetBaseException that works on .net but is broke...
[mono.git] / mcs / class / corlib / System.Threading.Tasks / TaskActionInvoker.cs
1 //
2 // TaskActionInvoker.cs
3 //
4 // Authors:
5 //    Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright 2011 Xamarin Inc.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 //
27 //
28
29 #if NET_4_0
30
31 using System.Threading;
32
33 namespace System.Threading.Tasks
34 {
35         abstract class TaskActionInvoker
36         {
37                 public static readonly TaskActionInvoker Empty = new EmptyTaskActionInvoker ();
38                 public static readonly TaskActionInvoker Delay = new DelayTaskInvoker ();
39                 
40                 sealed class EmptyTaskActionInvoker : TaskActionInvoker
41                 {
42                         public override Delegate Action {
43                                 get {
44                                         return null;
45                                 }
46                         }
47
48                         public override void Invoke (Task owner, object state, Task context)
49                         {
50                         }
51                 }
52
53                 sealed class ActionInvoke : TaskActionInvoker
54                 {
55                         readonly Action action;
56
57                         public ActionInvoke (Action action)
58                         {
59                                 this.action = action;
60                         }
61
62                         public override Delegate Action {
63                                 get {
64                                         return action;
65                                 }
66                         }
67
68                         public override void Invoke (Task owner, object state, Task context)
69                         {
70                                 action ();
71                         }
72                 }
73
74                 sealed class ActionObjectInvoke : TaskActionInvoker
75                 {
76                         readonly Action<object> action;
77
78                         public ActionObjectInvoke (Action<object> action)
79                         {
80                                 this.action = action;
81                         }
82
83                         public override Delegate Action {
84                                 get {
85                                         return action;
86                                 }
87                         }
88
89                         public override void Invoke (Task owner, object state, Task context)
90                         {
91                                 action (state);
92                         }
93                 }
94
95                 sealed class ActionTaskInvoke : TaskActionInvoker
96                 {
97                         readonly Action<Task> action;
98
99                         public ActionTaskInvoke (Action<Task> action)
100                         {
101                                 this.action = action;
102                         }
103
104                         public override Delegate Action {
105                                 get {
106                                         return action;
107                                 }
108                         }
109
110                         public override void Invoke (Task owner, object state, Task context)
111                         {
112                                 action (owner);
113                         }
114                 }
115
116                 sealed class ActionTasksInvoke : TaskActionInvoker
117                 {
118                         readonly Action<Task[]> action;
119                         readonly Task[] tasks;
120
121                         public ActionTasksInvoke (Action<Task[]> action, Task[] tasks)
122                         {
123                                 this.action = action;
124                                 this.tasks = tasks;
125                         }
126
127                         public override Delegate Action {
128                                 get {
129                                         return action;
130                                 }
131                         }
132
133                         public override void Invoke (Task owner, object state, Task context)
134                         {
135                                 owner.TrySetExceptionObserved ();
136                                 action (tasks);
137                         }
138                 }
139
140                 sealed class ActionTaskObjectInvoke : TaskActionInvoker
141                 {
142                         readonly Action<Task, object> action;
143
144                         public ActionTaskObjectInvoke (Action<Task, object> action)
145                         {
146                                 this.action = action;
147                         }
148
149                         public override Delegate Action {
150                                 get {
151                                         return action;
152                                 }
153                         }
154
155                         public override void Invoke (Task owner, object state, Task context)
156                         {
157                                 action (owner, state);
158                         }
159                 }
160
161                 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
162                 {
163                         readonly Action<Task<TResult>, object> action;
164
165                         public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
166                         {
167                                 this.action = action;
168                         }
169
170                         public override Delegate Action {
171                                 get {
172                                         return action;
173                                 }
174                         }
175
176                         public override void Invoke (Task owner, object state, Task context)
177                         {
178                                 action ((Task<TResult>) owner, state);
179                         }
180                 }
181
182                 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
183                 {
184                         readonly Action<Task<TResult>> action;
185
186                         public ActionTaskInvoke (Action<Task<TResult>> action)
187                         {
188                                 this.action = action;
189                         }
190
191                         public override Delegate Action {
192                                 get {
193                                         return action;
194                                 }
195                         }
196
197                         public override void Invoke (Task owner, object state, Task context)
198                         {
199                                 action ((Task<TResult>) owner);
200                         }
201                 }
202
203                 sealed class ActionTaskSelected : TaskActionInvoker
204                 {
205                         readonly Action<Task> action;
206
207                         public ActionTaskSelected (Action<Task> action)
208                         {
209                                 this.action = action;
210                         }
211
212                         public override Delegate Action {
213                                 get {
214                                         return action;
215                                 }
216                         }
217
218                         public override void Invoke (Task owner, object state, Task context)
219                         {
220                                 action (((Task<Task>)owner).Result);
221                         }
222                 }
223
224                 sealed class FuncInvoke<TResult> : TaskActionInvoker
225                 {
226                         readonly Func<TResult> action;
227
228                         public FuncInvoke (Func<TResult> action)
229                         {
230                                 this.action = action;
231                         }
232
233                         public override Delegate Action {
234                                 get {
235                                         return action;
236                                 }
237                         }
238
239                         public override void Invoke (Task owner, object state, Task context)
240                         {
241                                 ((Task<TResult>) context).Result = action ();
242                         }
243                 }
244
245                 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
246                 {
247                         readonly Func<Task, TResult> action;
248
249                         public FuncTaskInvoke (Func<Task, TResult> action)
250                         {
251                                 this.action = action;
252                         }
253
254                         public override Delegate Action {
255                                 get {
256                                         return action;
257                                 }
258                         }
259
260                         public override void Invoke (Task owner, object state, Task context)
261                         {
262                                 ((Task<TResult>) context).Result = action (owner);
263                         }
264                 }
265
266                 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
267                 {
268                         readonly Func<Task[], TResult> action;
269                         readonly Task[] tasks;
270
271                         public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
272                         {
273                                 this.action = action;
274                                 this.tasks = tasks;
275                         }
276
277                         public override Delegate Action {
278                                 get {
279                                         return action;
280                                 }
281                         }
282
283                         public override void Invoke (Task owner, object state, Task context)
284                         {
285                                 owner.TrySetExceptionObserved ();
286                                 ((Task<TResult>) context).Result = action (tasks);
287                         }
288                 }
289
290                 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
291                 {
292                         readonly Func<Task, TResult> action;
293
294                         public FuncTaskSelected (Func<Task, TResult> action)
295                         {
296                                 this.action = action;
297                         }
298
299                         public override Delegate Action {
300                                 get {
301                                         return action;
302                                 }
303                         }
304
305                         public override void Invoke (Task owner, object state, Task context)
306                         {
307                                 var result = ((Task<Task>) owner).Result;
308                                 ((Task<TResult>) context).Result = action (result);
309                         }
310                 }
311
312                 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
313                 {
314                         readonly Func<Task<TResult>, TNewResult> action;
315
316                         public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
317                         {
318                                 this.action = action;
319                         }
320
321                         public override Delegate Action {
322                                 get {
323                                         return action;
324                                 }
325                         }
326
327                         public override void Invoke (Task owner, object state, Task context)
328                         {
329                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
330                         }
331                 }
332
333                 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
334                 {
335                         readonly Func<object, TResult> action;
336
337                         public FuncObjectInvoke (Func<object, TResult> action)
338                         {
339                                 this.action = action;
340                         }
341
342                         public override Delegate Action {
343                                 get {
344                                         return action;
345                                 }
346                         }
347
348                         public override void Invoke (Task owner, object state, Task context)
349                         {
350                                 ((Task<TResult>) context).Result = action (state);
351                         }
352                 }
353
354                 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
355                 {
356                         readonly Func<Task, object, TResult> action;
357
358                         public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
359                         {
360                                 this.action = action;
361                         }
362
363                         public override Delegate Action {
364                                 get {
365                                         return action;
366                                 }
367                         }
368
369                         public override void Invoke (Task owner, object state, Task context)
370                         {
371                                 ((Task<TResult>) context).Result = action (owner, state);
372                         }
373                 }
374
375                 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
376                 {
377                         readonly Func<Task<TResult>, object, TNewResult> action;
378
379                         public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
380                         {
381                                 this.action = action;
382                         }
383
384                         public override Delegate Action {
385                                 get {
386                                         return action;
387                                 }
388                         }
389
390                         public override void Invoke (Task owner, object state, Task context)
391                         {
392                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
393                         }
394                 }
395
396                 sealed class DelayTaskInvoker : TaskActionInvoker
397                 {
398                         public override Delegate Action {
399                                 get {
400                                         return null;
401                                 }
402                         }
403
404                         public override void Invoke (Task owner, object state, Task context)
405                         {
406                                 var mre = new ManualResetEventSlim ();
407                                 int timeout = (int) state;
408                                 mre.Wait (timeout, context.CancellationToken);
409                         }
410                 }
411
412                 public static TaskActionInvoker Create (Action action)
413                 {
414                         return new ActionInvoke (action);
415                 }
416
417                 public static TaskActionInvoker Create (Action<object> action)
418                 {
419                         return new ActionObjectInvoke (action);
420                 }
421
422                 public static TaskActionInvoker Create (Action<Task> action)
423                 {
424                         return new ActionTaskInvoke (action);
425                 }
426
427                 public static TaskActionInvoker Create (Action<Task, object> action)
428                 {
429                         return new ActionTaskObjectInvoke (action);
430                 }
431
432                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
433                 {
434                         return new ActionTaskInvoke<TResult> (action);
435                 }
436
437                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
438                 {
439                         return new ActionTaskObjectInvoke<TResult> (action);
440                 }
441
442                 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
443                 {
444                         return new FuncInvoke<TResult> (action);
445                 }
446
447                 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
448                 {
449                         return new FuncObjectInvoke<TResult> (action);
450                 }
451
452                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
453                 {
454                         return new FuncTaskInvoke<TResult> (action);
455                 }
456
457                 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
458                 {
459                         return new FuncTaskObjectInvoke<TResult> (action);
460                 }
461
462                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
463                 {
464                         return new FuncTaskInvoke<TResult, TNewResult> (action);
465                 }
466
467                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
468                 {
469                         return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
470                 }
471
472                 #region Used by ContinueWhenAll
473
474                 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
475                 {
476                         return new ActionTasksInvoke (action, tasks);
477                 }
478
479                 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
480                 {
481                         return new FuncTasksInvoke<TResult> (action, tasks);
482                 }
483
484                 #endregion
485
486                 #region Used by ContinueWhenAny
487
488                 public static TaskActionInvoker CreateSelected (Action<Task> action)
489                 {
490                         return new ActionTaskSelected (action);
491                 }
492
493                 public static TaskActionInvoker CreateSelected<TResult> (Func<Task, TResult> action)
494                 {
495                         return new FuncTaskSelected<TResult> (action);
496                 }
497
498                 #endregion
499
500                 public abstract Delegate Action { get; }
501                 public abstract void Invoke (Task owner, object state, Task context);
502         }
503 }
504 #endif