Implement more Task 4.5 members
[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 || MOBILE
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                                 action (tasks);
136                         }
137                 }
138
139                 sealed class ActionTaskObjectInvoke : TaskActionInvoker
140                 {
141                         readonly Action<Task, object> action;
142
143                         public ActionTaskObjectInvoke (Action<Task, object> action)
144                         {
145                                 this.action = action;
146                         }
147
148                         public override Delegate Action {
149                                 get {
150                                         return action;
151                                 }
152                         }
153
154                         public override void Invoke (Task owner, object state, Task context)
155                         {
156                                 action (owner, state);
157                         }
158                 }
159
160                 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
161                 {
162                         readonly Action<Task<TResult>, object> action;
163
164                         public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
165                         {
166                                 this.action = action;
167                         }
168
169                         public override Delegate Action {
170                                 get {
171                                         return action;
172                                 }
173                         }
174
175                         public override void Invoke (Task owner, object state, Task context)
176                         {
177                                 action ((Task<TResult>) owner, state);
178                         }
179                 }
180
181                 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
182                 {
183                         readonly Action<Task<TResult>> action;
184
185                         public ActionTaskInvoke (Action<Task<TResult>> action)
186                         {
187                                 this.action = action;
188                         }
189
190                         public override Delegate Action {
191                                 get {
192                                         return action;
193                                 }
194                         }
195
196                         public override void Invoke (Task owner, object state, Task context)
197                         {
198                                 action ((Task<TResult>) owner);
199                         }
200                 }
201
202                 sealed class ActionTaskSelected : TaskActionInvoker
203                 {
204                         readonly Action<Task> action;
205                         readonly Task[] tasks;
206
207                         public ActionTaskSelected (Action<Task> action, Task[] tasks)
208                         {
209                                 this.action = action;
210                                 this.tasks = tasks;
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                                 var result = ((Task<int>) owner).Result;
222                                 action (tasks [result]);
223                         }
224                 }
225
226                 sealed class FuncInvoke<TResult> : TaskActionInvoker
227                 {
228                         readonly Func<TResult> action;
229
230                         public FuncInvoke (Func<TResult> action)
231                         {
232                                 this.action = action;
233                         }
234
235                         public override Delegate Action {
236                                 get {
237                                         return action;
238                                 }
239                         }
240
241                         public override void Invoke (Task owner, object state, Task context)
242                         {
243                                 ((Task<TResult>) context).Result = action ();
244                         }
245                 }
246
247                 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
248                 {
249                         readonly Func<Task, TResult> action;
250
251                         public FuncTaskInvoke (Func<Task, TResult> action)
252                         {
253                                 this.action = action;
254                         }
255
256                         public override Delegate Action {
257                                 get {
258                                         return action;
259                                 }
260                         }
261
262                         public override void Invoke (Task owner, object state, Task context)
263                         {
264                                 ((Task<TResult>) context).Result = action (owner);
265                         }
266                 }
267
268                 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
269                 {
270                         readonly Func<Task[], TResult> action;
271                         readonly Task[] tasks;
272
273                         public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
274                         {
275                                 this.action = action;
276                                 this.tasks = tasks;
277                         }
278
279                         public override Delegate Action {
280                                 get {
281                                         return action;
282                                 }
283                         }
284
285                         public override void Invoke (Task owner, object state, Task context)
286                         {
287                                 ((Task<TResult>) context).Result = action (tasks);
288                         }
289                 }
290
291                 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
292                 {
293                         readonly Func<Task, TResult> action;
294                         readonly Task[] tasks;
295
296                         public FuncTaskSelected (Func<Task, TResult> action, Task[] tasks)
297                         {
298                                 this.action = action;
299                                 this.tasks = tasks;
300                         }
301
302                         public override Delegate Action {
303                                 get {
304                                         return action;
305                                 }
306                         }
307
308                         public override void Invoke (Task owner, object state, Task context)
309                         {
310                                 var result = ((Task<int>) owner).Result;
311                                 ((Task<TResult>) context).Result = action (tasks[result]);
312                         }
313                 }
314
315                 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
316                 {
317                         readonly Func<Task<TResult>, TNewResult> action;
318
319                         public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
320                         {
321                                 this.action = action;
322                         }
323
324                         public override Delegate Action {
325                                 get {
326                                         return action;
327                                 }
328                         }
329
330                         public override void Invoke (Task owner, object state, Task context)
331                         {
332                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
333                         }
334                 }
335
336                 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
337                 {
338                         readonly Func<object, TResult> action;
339
340                         public FuncObjectInvoke (Func<object, TResult> action)
341                         {
342                                 this.action = action;
343                         }
344
345                         public override Delegate Action {
346                                 get {
347                                         return action;
348                                 }
349                         }
350
351                         public override void Invoke (Task owner, object state, Task context)
352                         {
353                                 ((Task<TResult>) context).Result = action (state);
354                         }
355                 }
356
357                 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
358                 {
359                         readonly Func<Task, object, TResult> action;
360
361                         public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
362                         {
363                                 this.action = action;
364                         }
365
366                         public override Delegate Action {
367                                 get {
368                                         return action;
369                                 }
370                         }
371
372                         public override void Invoke (Task owner, object state, Task context)
373                         {
374                                 ((Task<TResult>) context).Result = action (owner, state);
375                         }
376                 }
377
378                 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
379                 {
380                         readonly Func<Task<TResult>, object, TNewResult> action;
381
382                         public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
383                         {
384                                 this.action = action;
385                         }
386
387                         public override Delegate Action {
388                                 get {
389                                         return action;
390                                 }
391                         }
392
393                         public override void Invoke (Task owner, object state, Task context)
394                         {
395                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
396                         }
397                 }
398
399                 sealed class DelayTaskInvoker : TaskActionInvoker
400                 {
401                         public override Delegate Action {
402                                 get {
403                                         return null;
404                                 }
405                         }
406
407                         public override void Invoke (Task owner, object state, Task context)
408                         {
409                                 var mre = new ManualResetEventSlim ();
410                                 int timeout = (int) state;
411                                 mre.Wait (timeout, owner.CancellationToken);
412                         }
413                 }
414
415                 public static TaskActionInvoker Create (Action action)
416                 {
417                         return new ActionInvoke (action);
418                 }
419
420                 public static TaskActionInvoker Create (Action<object> action)
421                 {
422                         return new ActionObjectInvoke (action);
423                 }
424
425                 public static TaskActionInvoker Create (Action<Task> action)
426                 {
427                         return new ActionTaskInvoke (action);
428                 }
429
430                 public static TaskActionInvoker Create (Action<Task, object> action)
431                 {
432                         return new ActionTaskObjectInvoke (action);
433                 }
434
435                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
436                 {
437                         return new ActionTaskInvoke<TResult> (action);
438                 }
439
440                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
441                 {
442                         return new ActionTaskObjectInvoke<TResult> (action);
443                 }
444
445                 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
446                 {
447                         return new FuncInvoke<TResult> (action);
448                 }
449
450                 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
451                 {
452                         return new FuncObjectInvoke<TResult> (action);
453                 }
454
455                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
456                 {
457                         return new FuncTaskInvoke<TResult> (action);
458                 }
459
460                 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
461                 {
462                         return new FuncTaskObjectInvoke<TResult> (action);
463                 }
464
465                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
466                 {
467                         return new FuncTaskInvoke<TResult, TNewResult> (action);
468                 }
469
470                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
471                 {
472                         return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
473                 }
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                 #region Used by WhenAny
486
487                 public static TaskActionInvoker Create (Action<Task> action, Task[] tasks)
488                 {
489                         return new ActionTaskSelected (action, tasks);
490                 }
491
492                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action, Task[] tasks)
493                 {
494                         return new FuncTaskSelected<TResult> (action, tasks);
495                 }
496
497                 #endregion
498
499                 public abstract Delegate Action { get; }
500                 public abstract void Invoke (Task owner, object state, Task context);
501         }
502 }
503 #endif