Merge pull request #297 from ermshiperete/4959
[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
206                         public ActionTaskSelected (Action<Task> action)
207                         {
208                                 this.action = action;
209                         }
210
211                         public override Delegate Action {
212                                 get {
213                                         return action;
214                                 }
215                         }
216
217                         public override void Invoke (Task owner, object state, Task context)
218                         {
219                                 action (((Task<Task>)owner).Result);
220                         }
221                 }
222
223                 sealed class FuncInvoke<TResult> : TaskActionInvoker
224                 {
225                         readonly Func<TResult> action;
226
227                         public FuncInvoke (Func<TResult> action)
228                         {
229                                 this.action = action;
230                         }
231
232                         public override Delegate Action {
233                                 get {
234                                         return action;
235                                 }
236                         }
237
238                         public override void Invoke (Task owner, object state, Task context)
239                         {
240                                 ((Task<TResult>) context).Result = action ();
241                         }
242                 }
243
244                 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
245                 {
246                         readonly Func<Task, TResult> action;
247
248                         public FuncTaskInvoke (Func<Task, TResult> action)
249                         {
250                                 this.action = action;
251                         }
252
253                         public override Delegate Action {
254                                 get {
255                                         return action;
256                                 }
257                         }
258
259                         public override void Invoke (Task owner, object state, Task context)
260                         {
261                                 ((Task<TResult>) context).Result = action (owner);
262                         }
263                 }
264
265                 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
266                 {
267                         readonly Func<Task[], TResult> action;
268                         readonly Task[] tasks;
269
270                         public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
271                         {
272                                 this.action = action;
273                                 this.tasks = tasks;
274                         }
275
276                         public override Delegate Action {
277                                 get {
278                                         return action;
279                                 }
280                         }
281
282                         public override void Invoke (Task owner, object state, Task context)
283                         {
284                                 ((Task<TResult>) context).Result = action (tasks);
285                         }
286                 }
287
288                 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
289                 {
290                         readonly Func<Task, TResult> action;
291                         readonly Task[] tasks;
292
293                         public FuncTaskSelected (Func<Task, TResult> action, Task[] tasks)
294                         {
295                                 this.action = action;
296                                 this.tasks = tasks;
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<int>) owner).Result;
308                                 ((Task<TResult>) context).Result = action (tasks[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                 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
473                 {
474                         return new ActionTasksInvoke (action, tasks);
475                 }
476
477                 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
478                 {
479                         return new FuncTasksInvoke<TResult> (action, tasks);
480                 }
481
482                 #region Used by WhenAny
483
484                 public static TaskActionInvoker CreateSelected (Action<Task> action)
485                 {
486                         return new ActionTaskSelected (action);
487                 }
488
489                 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action, Task[] tasks)
490                 {
491                         return new FuncTaskSelected<TResult> (action, tasks);
492                 }
493
494                 #endregion
495
496                 public abstract Delegate Action { get; }
497                 public abstract void Invoke (Task owner, object state, Task context);
498         }
499 }
500 #endif