2 // TaskActionInvoker.cs
5 // Marek Safar <marek.safar@gmail.com>
7 // Copyright 2011 Xamarin Inc.
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:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
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
31 using System.Threading;
33 namespace System.Threading.Tasks
35 abstract class TaskActionInvoker
37 public static readonly TaskActionInvoker Empty = new EmptyTaskActionInvoker ();
38 public static readonly TaskActionInvoker Delay = new DelayTaskInvoker ();
40 sealed class EmptyTaskActionInvoker : TaskActionInvoker
42 public override Delegate Action {
48 public override void Invoke (Task owner, object state, Task context)
53 sealed class ActionInvoke : TaskActionInvoker
55 readonly Action action;
57 public ActionInvoke (Action action)
62 public override Delegate Action {
68 public override void Invoke (Task owner, object state, Task context)
74 sealed class ActionObjectInvoke : TaskActionInvoker
76 readonly Action<object> action;
78 public ActionObjectInvoke (Action<object> action)
83 public override Delegate Action {
89 public override void Invoke (Task owner, object state, Task context)
95 sealed class ActionTaskInvoke : TaskActionInvoker
97 readonly Action<Task> action;
99 public ActionTaskInvoke (Action<Task> action)
101 this.action = action;
104 public override Delegate Action {
110 public override void Invoke (Task owner, object state, Task context)
116 sealed class ActionTasksInvoke : TaskActionInvoker
118 readonly Action<Task[]> action;
119 readonly Task[] tasks;
121 public ActionTasksInvoke (Action<Task[]> action, Task[] tasks)
123 this.action = action;
127 public override Delegate Action {
133 public override void Invoke (Task owner, object state, Task context)
135 owner.TrySetExceptionObserved ();
140 sealed class ActionTaskObjectInvoke : TaskActionInvoker
142 readonly Action<Task, object> action;
144 public ActionTaskObjectInvoke (Action<Task, object> action)
146 this.action = action;
149 public override Delegate Action {
155 public override void Invoke (Task owner, object state, Task context)
157 action (owner, state);
161 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
163 readonly Action<Task<TResult>, object> action;
165 public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
167 this.action = action;
170 public override Delegate Action {
176 public override void Invoke (Task owner, object state, Task context)
178 action ((Task<TResult>) owner, state);
182 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
184 readonly Action<Task<TResult>> action;
186 public ActionTaskInvoke (Action<Task<TResult>> action)
188 this.action = action;
191 public override Delegate Action {
197 public override void Invoke (Task owner, object state, Task context)
199 action ((Task<TResult>) owner);
203 sealed class ActionTaskSelected : TaskActionInvoker
205 readonly Action<Task> action;
207 public ActionTaskSelected (Action<Task> action)
209 this.action = action;
212 public override Delegate Action {
218 public override void Invoke (Task owner, object state, Task context)
220 action (((Task<Task>)owner).Result);
224 sealed class FuncInvoke<TResult> : TaskActionInvoker
226 readonly Func<TResult> action;
228 public FuncInvoke (Func<TResult> action)
230 this.action = action;
233 public override Delegate Action {
239 public override void Invoke (Task owner, object state, Task context)
241 ((Task<TResult>) context).Result = action ();
245 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
247 readonly Func<Task, TResult> action;
249 public FuncTaskInvoke (Func<Task, TResult> action)
251 this.action = action;
254 public override Delegate Action {
260 public override void Invoke (Task owner, object state, Task context)
262 ((Task<TResult>) context).Result = action (owner);
266 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
268 readonly Func<Task[], TResult> action;
269 readonly Task[] tasks;
271 public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
273 this.action = action;
277 public override Delegate Action {
283 public override void Invoke (Task owner, object state, Task context)
285 owner.TrySetExceptionObserved ();
286 ((Task<TResult>) context).Result = action (tasks);
290 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
292 readonly Func<Task, TResult> action;
293 readonly Task[] tasks;
295 public FuncTaskSelected (Func<Task, TResult> action, Task[] tasks)
297 this.action = action;
301 public override Delegate Action {
307 public override void Invoke (Task owner, object state, Task context)
309 var result = ((Task<int>) owner).Result;
310 ((Task<TResult>) context).Result = action (tasks[result]);
314 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
316 readonly Func<Task<TResult>, TNewResult> action;
318 public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
320 this.action = action;
323 public override Delegate Action {
329 public override void Invoke (Task owner, object state, Task context)
331 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
335 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
337 readonly Func<object, TResult> action;
339 public FuncObjectInvoke (Func<object, TResult> action)
341 this.action = action;
344 public override Delegate Action {
350 public override void Invoke (Task owner, object state, Task context)
352 ((Task<TResult>) context).Result = action (state);
356 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
358 readonly Func<Task, object, TResult> action;
360 public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
362 this.action = action;
365 public override Delegate Action {
371 public override void Invoke (Task owner, object state, Task context)
373 ((Task<TResult>) context).Result = action (owner, state);
377 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
379 readonly Func<Task<TResult>, object, TNewResult> action;
381 public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
383 this.action = action;
386 public override Delegate Action {
392 public override void Invoke (Task owner, object state, Task context)
394 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
398 sealed class DelayTaskInvoker : TaskActionInvoker
400 public override Delegate Action {
406 public override void Invoke (Task owner, object state, Task context)
408 var mre = new ManualResetEventSlim ();
409 int timeout = (int) state;
410 mre.Wait (timeout, context.CancellationToken);
414 public static TaskActionInvoker Create (Action action)
416 return new ActionInvoke (action);
419 public static TaskActionInvoker Create (Action<object> action)
421 return new ActionObjectInvoke (action);
424 public static TaskActionInvoker Create (Action<Task> action)
426 return new ActionTaskInvoke (action);
429 public static TaskActionInvoker Create (Action<Task, object> action)
431 return new ActionTaskObjectInvoke (action);
434 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
436 return new ActionTaskInvoke<TResult> (action);
439 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
441 return new ActionTaskObjectInvoke<TResult> (action);
444 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
446 return new FuncInvoke<TResult> (action);
449 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
451 return new FuncObjectInvoke<TResult> (action);
454 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
456 return new FuncTaskInvoke<TResult> (action);
459 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
461 return new FuncTaskObjectInvoke<TResult> (action);
464 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
466 return new FuncTaskInvoke<TResult, TNewResult> (action);
469 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
471 return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
474 #region Used by ContinueWhenAll
476 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
478 return new ActionTasksInvoke (action, tasks);
481 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
483 return new FuncTasksInvoke<TResult> (action, tasks);
488 #region Used by ContinueWhenAny
490 public static TaskActionInvoker CreateSelected (Action<Task> action)
492 return new ActionTaskSelected (action);
495 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action, Task[] tasks)
497 return new FuncTaskSelected<TResult> (action, tasks);
502 public abstract Delegate Action { get; }
503 public abstract void Invoke (Task owner, object state, Task context);