Merge pull request #498 from Unroll-Me/master
[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                                 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                         readonly Task[] tasks;
294
295                         public FuncTaskSelected (Func<Task, TResult> action, Task[] tasks)
296                         {
297                                 this.action = action;
298                                 this.tasks = tasks;
299                         }
300
301                         public override Delegate Action {
302                                 get {
303                                         return action;
304                                 }
305                         }
306
307                         public override void Invoke (Task owner, object state, Task context)
308                         {
309                                 var result = ((Task<int>) owner).Result;
310                                 ((Task<TResult>) context).Result = action (tasks[result]);
311                         }
312                 }
313
314                 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
315                 {
316                         readonly Func<Task<TResult>, TNewResult> action;
317
318                         public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
319                         {
320                                 this.action = action;
321                         }
322
323                         public override Delegate Action {
324                                 get {
325                                         return action;
326                                 }
327                         }
328
329                         public override void Invoke (Task owner, object state, Task context)
330                         {
331                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
332                         }
333                 }
334
335                 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
336                 {
337                         readonly Func<object, TResult> action;
338
339                         public FuncObjectInvoke (Func<object, TResult> action)
340                         {
341                                 this.action = action;
342                         }
343
344                         public override Delegate Action {
345                                 get {
346                                         return action;
347                                 }
348                         }
349
350                         public override void Invoke (Task owner, object state, Task context)
351                         {
352                                 ((Task<TResult>) context).Result = action (state);
353                         }
354                 }
355
356                 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
357                 {
358                         readonly Func<Task, object, TResult> action;
359
360                         public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
361                         {
362                                 this.action = action;
363                         }
364
365                         public override Delegate Action {
366                                 get {
367                                         return action;
368                                 }
369                         }
370
371                         public override void Invoke (Task owner, object state, Task context)
372                         {
373                                 ((Task<TResult>) context).Result = action (owner, state);
374                         }
375                 }
376
377                 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
378                 {
379                         readonly Func<Task<TResult>, object, TNewResult> action;
380
381                         public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
382                         {
383                                 this.action = action;
384                         }
385
386                         public override Delegate Action {
387                                 get {
388                                         return action;
389                                 }
390                         }
391
392                         public override void Invoke (Task owner, object state, Task context)
393                         {
394                                 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
395                         }
396                 }
397
398                 sealed class DelayTaskInvoker : TaskActionInvoker
399                 {
400                         public override Delegate Action {
401                                 get {
402                                         return null;
403                                 }
404                         }
405
406                         public override void Invoke (Task owner, object state, Task context)
407                         {
408                                 var mre = new ManualResetEventSlim ();
409                                 int timeout = (int) state;
410                                 mre.Wait (timeout, context.CancellationToken);
411                         }
412                 }
413
414                 public static TaskActionInvoker Create (Action action)
415                 {
416                         return new ActionInvoke (action);
417                 }
418
419                 public static TaskActionInvoker Create (Action<object> action)
420                 {
421                         return new ActionObjectInvoke (action);
422                 }
423
424                 public static TaskActionInvoker Create (Action<Task> action)
425                 {
426                         return new ActionTaskInvoke (action);
427                 }
428
429                 public static TaskActionInvoker Create (Action<Task, object> action)
430                 {
431                         return new ActionTaskObjectInvoke (action);
432                 }
433
434                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
435                 {
436                         return new ActionTaskInvoke<TResult> (action);
437                 }
438
439                 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
440                 {
441                         return new ActionTaskObjectInvoke<TResult> (action);
442                 }
443
444                 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
445                 {
446                         return new FuncInvoke<TResult> (action);
447                 }
448
449                 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
450                 {
451                         return new FuncObjectInvoke<TResult> (action);
452                 }
453
454                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
455                 {
456                         return new FuncTaskInvoke<TResult> (action);
457                 }
458
459                 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
460                 {
461                         return new FuncTaskObjectInvoke<TResult> (action);
462                 }
463
464                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
465                 {
466                         return new FuncTaskInvoke<TResult, TNewResult> (action);
467                 }
468
469                 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
470                 {
471                         return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
472                 }
473
474                 #region Used by ContinueWhenAll
475
476                 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
477                 {
478                         return new ActionTasksInvoke (action, tasks);
479                 }
480
481                 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
482                 {
483                         return new FuncTasksInvoke<TResult> (action, tasks);
484                 }
485
486                 #endregion
487
488                 #region Used by ContinueWhenAny
489
490                 public static TaskActionInvoker CreateSelected (Action<Task> action)
491                 {
492                         return new ActionTaskSelected (action);
493                 }
494
495                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action, Task[] tasks)
496                 {
497                         return new FuncTaskSelected<TResult> (action, tasks);
498                 }
499
500                 #endregion
501
502                 public abstract Delegate Action { get; }
503                 public abstract void Invoke (Task owner, object state, Task context);
504         }
505 }
506 #endif