TaskActionInvoker.cs
Go to the documentation of this file.
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  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