Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[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 Promise = new EmptyTaskActionInvoker ();
39                 public static readonly TaskActionInvoker Delay = new DelayTaskInvoker ();
40                 
41                 sealed class EmptyTaskActionInvoker : TaskActionInvoker
42                 {
43                         public override Delegate Action {
44                                 get {
45                                         return null;
46                                 }
47                         }
48
49                         public override void Invoke (Task owner, object state, Task context)
50                         {
51                         }
52                 }
53
54                 sealed class ActionInvoke : TaskActionInvoker
55                 {
56                         readonly Action action;
57
58                         public ActionInvoke (Action action)
59                         {
60                                 this.action = action;
61                         }
62
63                         public override Delegate Action {
64                                 get {
65                                         return action;
66                                 }
67                         }
68
69                         public override void Invoke (Task owner, object state, Task context)
70                         {
71                                 action ();
72                         }
73                 }
74
75                 sealed class ActionObjectInvoke : TaskActionInvoker
76                 {
77                         readonly Action<object> action;
78
79                         public ActionObjectInvoke (Action<object> action)
80                         {
81                                 this.action = action;
82                         }
83
84                         public override Delegate Action {
85                                 get {
86                                         return action;
87                                 }
88                         }
89
90                         public override void Invoke (Task owner, object state, Task context)
91                         {
92                                 action (state);
93                         }
94                 }
95
96                 sealed class ActionTaskInvoke : TaskActionInvoker
97                 {
98                         readonly Action<Task> action;
99
100                         public ActionTaskInvoke (Action<Task> action)
101                         {
102                                 this.action = action;
103                         }
104
105                         public override Delegate Action {
106                                 get {
107                                         return action;
108                                 }
109                         }
110
111                         public override void Invoke (Task owner, object state, Task context)
112                         {
113                                 action (owner);
114                         }
115                 }
116
117                 sealed class ActionTasksInvoke : TaskActionInvoker
118                 {
119                         readonly Action<Task[]> action;
120                         readonly Task[] tasks;
121
122                         public ActionTasksInvoke (Action<Task[]> action, Task[] tasks)
123                         {
124                                 this.action = action;
125                                 this.tasks = tasks;
126                         }
127
128                         public override Delegate Action {
129                                 get {
130                                         return action;
131                                 }
132                         }
133
134                         public override void Invoke (Task owner, object state, Task context)
135                         {
136                                 owner.TrySetExceptionObserved ();
137                                 action (tasks);
138                         }
139                 }
140
141                 sealed class ActionTaskObjectInvoke : TaskActionInvoker
142                 {
143                         readonly Action<Task, object> action;
144
145                         public ActionTaskObjectInvoke (Action<Task, object> action)
146                         {
147                                 this.action = action;
148                         }
149
150                         public override Delegate Action {
151                                 get {
152                                         return action;
153                                 }
154                         }
155
156                         public override void Invoke (Task owner, object state, Task context)
157                         {
158                                 action (owner, state);
159                         }
160                 }
161
162                 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
163                 {
164                         readonly Action<Task<TResult>, object> action;
165
166                         public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
167                         {
168                                 this.action = action;
169                         }
170
171                         public override Delegate Action {
172                                 get {
173                                         return action;
174                                 }
175                         }
176
177                         public override void Invoke (Task owner, object state, Task context)
178                         {
179                                 action ((Task<TResult>) owner, state);
180                         }
181                 }
182
183                 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
184                 {
185                         readonly Action<Task<TResult>> action;
186
187                         public ActionTaskInvoke (Action<Task<TResult>> action)
188                         {
189                                 this.action = action;
190                         }
191
192                         public override Delegate Action {
193                                 get {
194                                         return action;
195                                 }
196                         }
197
198                         public override void Invoke (Task owner, object state, Task context)
199                         {
200                                 action ((Task<TResult>) owner);
201                         }
202                 }
203
204                 sealed class ActionTaskSelected : TaskActionInvoker
205                 {
206                         readonly Action<Task> action;
207
208                         public ActionTaskSelected (Action<Task> action)
209                         {
210                                 this.action = action;
211                         }
212
213                         public override Delegate Action {
214                                 get {
215                                         return action;
216                                 }
217                         }
218
219                         public override void Invoke (Task owner, object state, Task context)
220                         {
221                                 action (((Task<Task>)owner).Result);
222                         }
223                 }
224
225                 sealed class FuncInvoke<TResult> : TaskActionInvoker
226                 {
227                         readonly Func<TResult> action;
228
229                         public FuncInvoke (Func<TResult> action)
230                         {
231                                 this.action = action;
232                         }
233
234                         public override Delegate Action {
235                                 get {
236                                         return action;
237                                 }
238                         }
239
240                         public override void Invoke (Task owner, object state, Task context)
241                         {
242                                 ((Task<TResult>) context).Result = action ();
243                         }
244                 }
245
246                 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
247                 {
248                         readonly Func<Task, TResult> action;
249
250                         public FuncTaskInvoke (Func<Task, TResult> action)
251                         {
252                                 this.action = action;
253                         }
254
255                         public override Delegate Action {
256                                 get {
257                                         return action;
258                                 }
259                         }
260
261                         public override void Invoke (Task owner, object state, Task context)
262                         {
263                                 ((Task<TResult>) context).Result = action (owner);
264                         }
265                 }
266
267                 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
268                 {
269                         readonly Func<Task[], TResult> action;
270                         readonly Task[] tasks;
271
272                         public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
273                         {
274                                 this.action = action;
275                                 this.tasks = tasks;
276                         }
277
278                         public override Delegate Action {
279                                 get {
280                                         return action;
281                                 }
282                         }
283
284                         public override void Invoke (Task owner, object state, Task context)
285                         {
286                                 owner.TrySetExceptionObserved ();
287                                 ((Task<TResult>) context).Result = action (tasks);
288                         }
289                 }
290
291                 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
292                 {
293                         readonly Func<Task, TResult> action;
294
295                         public FuncTaskSelected (Func<Task, TResult> action)
296                         {
297                                 this.action = action;
298                         }
299
300                         public override Delegate Action {
301                                 get {
302                                         return action;
303                                 }
304                         }
305
306                         public override void Invoke (Task owner, object state, Task context)
307                         {
308                                 var result = ((Task<Task>) owner).Result;
309                                 ((Task<TResult>) context).Result = action (result);
310                         }
311                 }
312
313                 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
314                 {
315                         readonly Func<Task<TResult>, TNewResult> action;
316
317                         public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
318                         {
319                                 this.action = action;
320                         }
321
322                         public override Delegate Action {
323                                 get {
324                                         return action;
325                                 }
326                         }
327
328                         public override void Invoke (Task owner, object state, Task context)
329                         {
330                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
331                         }
332                 }
333
334                 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
335                 {
336                         readonly Func<object, TResult> action;
337
338                         public FuncObjectInvoke (Func<object, TResult> action)
339                         {
340                                 this.action = action;
341                         }
342
343                         public override Delegate Action {
344                                 get {
345                                         return action;
346                                 }
347                         }
348
349                         public override void Invoke (Task owner, object state, Task context)
350                         {
351                                 ((Task<TResult>) context).Result = action (state);
352                         }
353                 }
354
355                 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
356                 {
357                         readonly Func<Task, object, TResult> action;
358
359                         public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
360                         {
361                                 this.action = action;
362                         }
363
364                         public override Delegate Action {
365                                 get {
366                                         return action;
367                                 }
368                         }
369
370                         public override void Invoke (Task owner, object state, Task context)
371                         {
372                                 ((Task<TResult>) context).Result = action (owner, state);
373                         }
374                 }
375
376                 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
377                 {
378                         readonly Func<Task<TResult>, object, TNewResult> action;
379
380                         public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
381                         {
382                                 this.action = action;
383                         }
384
385                         public override Delegate Action {
386                                 get {
387                                         return action;
388                                 }
389                         }
390
391                         public override void Invoke (Task owner, object state, Task context)
392                         {
393                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
394                         }
395                 }
396
397                 sealed class DelayTaskInvoker : TaskActionInvoker
398                 {
399                         public override Delegate Action {
400                                 get {
401                                         return null;
402                                 }
403                         }
404
405                         public override void Invoke (Task owner, object state, Task context)
406                         {
407                                 var mre = new ManualResetEventSlim ();
408                                 int timeout = (int) state;
409                                 mre.Wait (timeout, context.CancellationToken);
410                         }
411                 }
412
413                 public static TaskActionInvoker Create (Action action)
414                 {
415                         return new ActionInvoke (action);
416                 }
417
418                 public static TaskActionInvoker Create (Action<object> action)
419                 {
420                         return new ActionObjectInvoke (action);
421                 }
422
423                 public static TaskActionInvoker Create (Action<Task> action)
424                 {
425                         return new ActionTaskInvoke (action);
426                 }
427
428                 public static TaskActionInvoker Create (Action<Task, object> action)
429                 {
430                         return new ActionTaskObjectInvoke (action);
431                 }
432
433                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
434                 {
435                         return new ActionTaskInvoke<TResult> (action);
436                 }
437
438                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
439                 {
440                         return new ActionTaskObjectInvoke<TResult> (action);
441                 }
442
443                 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
444                 {
445                         return new FuncInvoke<TResult> (action);
446                 }
447
448                 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
449                 {
450                         return new FuncObjectInvoke<TResult> (action);
451                 }
452
453                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
454                 {
455                         return new FuncTaskInvoke<TResult> (action);
456                 }
457
458                 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
459                 {
460                         return new FuncTaskObjectInvoke<TResult> (action);
461                 }
462
463                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
464                 {
465                         return new FuncTaskInvoke<TResult, TNewResult> (action);
466                 }
467
468                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
469                 {
470                         return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
471                 }
472
473                 #region Used by ContinueWhenAll
474
475                 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
476                 {
477                         return new ActionTasksInvoke (action, tasks);
478                 }
479
480                 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
481                 {
482                         return new FuncTasksInvoke<TResult> (action, tasks);
483                 }
484
485                 #endregion
486
487                 #region Used by ContinueWhenAny
488
489                 public static TaskActionInvoker CreateSelected (Action<Task> action)
490                 {
491                         return new ActionTaskSelected (action);
492                 }
493
494                 public static TaskActionInvoker CreateSelected<TResult> (Func<Task, TResult> action)
495                 {
496                         return new FuncTaskSelected<TResult> (action);
497                 }
498
499                 #endregion
500
501                 public abstract Delegate Action { get; }
502                 public abstract void Invoke (Task owner, object state, Task context);
503         }
504 }
505 #endif