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)
139 sealed class ActionTaskObjectInvoke : TaskActionInvoker
141 readonly Action<Task, object> action;
143 public ActionTaskObjectInvoke (Action<Task, object> action)
145 this.action = action;
148 public override Delegate Action {
154 public override void Invoke (Task owner, object state, Task context)
156 action (owner, state);
160 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
162 readonly Action<Task<TResult>, object> action;
164 public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
166 this.action = action;
169 public override Delegate Action {
175 public override void Invoke (Task owner, object state, Task context)
177 action ((Task<TResult>) owner, state);
181 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
183 readonly Action<Task<TResult>> action;
185 public ActionTaskInvoke (Action<Task<TResult>> action)
187 this.action = action;
190 public override Delegate Action {
196 public override void Invoke (Task owner, object state, Task context)
198 action ((Task<TResult>) owner);
202 sealed class ActionTaskSelected : TaskActionInvoker
204 readonly Action<Task> action;
205 readonly Task[] tasks;
207 public ActionTaskSelected (Action<Task> action, Task[] tasks)
209 this.action = action;
213 public override Delegate Action {
219 public override void Invoke (Task owner, object state, Task context)
221 var result = ((Task<int>) owner).Result;
222 action (tasks [result]);
226 sealed class FuncInvoke<TResult> : TaskActionInvoker
228 readonly Func<TResult> action;
230 public FuncInvoke (Func<TResult> action)
232 this.action = action;
235 public override Delegate Action {
241 public override void Invoke (Task owner, object state, Task context)
243 ((Task<TResult>) context).Result = action ();
247 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
249 readonly Func<Task, TResult> action;
251 public FuncTaskInvoke (Func<Task, TResult> action)
253 this.action = action;
256 public override Delegate Action {
262 public override void Invoke (Task owner, object state, Task context)
264 ((Task<TResult>) context).Result = action (owner);
268 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
270 readonly Func<Task[], TResult> action;
271 readonly Task[] tasks;
273 public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
275 this.action = action;
279 public override Delegate Action {
285 public override void Invoke (Task owner, object state, Task context)
287 ((Task<TResult>) context).Result = action (tasks);
291 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
293 readonly Func<Task, TResult> action;
294 readonly Task[] tasks;
296 public FuncTaskSelected (Func<Task, TResult> action, Task[] tasks)
298 this.action = action;
302 public override Delegate Action {
308 public override void Invoke (Task owner, object state, Task context)
310 var result = ((Task<int>) owner).Result;
311 ((Task<TResult>) context).Result = action (tasks[result]);
315 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
317 readonly Func<Task<TResult>, TNewResult> action;
319 public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
321 this.action = action;
324 public override Delegate Action {
330 public override void Invoke (Task owner, object state, Task context)
332 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
336 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
338 readonly Func<object, TResult> action;
340 public FuncObjectInvoke (Func<object, TResult> action)
342 this.action = action;
345 public override Delegate Action {
351 public override void Invoke (Task owner, object state, Task context)
353 ((Task<TResult>) context).Result = action (state);
357 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
359 readonly Func<Task, object, TResult> action;
361 public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
363 this.action = action;
366 public override Delegate Action {
372 public override void Invoke (Task owner, object state, Task context)
374 ((Task<TResult>) context).Result = action (owner, state);
378 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
380 readonly Func<Task<TResult>, object, TNewResult> action;
382 public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
384 this.action = action;
387 public override Delegate Action {
393 public override void Invoke (Task owner, object state, Task context)
395 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
399 sealed class DelayTaskInvoker : TaskActionInvoker
401 public override Delegate Action {
407 public override void Invoke (Task owner, object state, Task context)
409 var mre = new ManualResetEventSlim ();
410 int timeout = (int) state;
411 mre.Wait (timeout, owner.CancellationToken);
415 public static TaskActionInvoker Create (Action action)
417 return new ActionInvoke (action);
420 public static TaskActionInvoker Create (Action<object> action)
422 return new ActionObjectInvoke (action);
425 public static TaskActionInvoker Create (Action<Task> action)
427 return new ActionTaskInvoke (action);
430 public static TaskActionInvoker Create (Action<Task, object> action)
432 return new ActionTaskObjectInvoke (action);
435 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
437 return new ActionTaskInvoke<TResult> (action);
440 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
442 return new ActionTaskObjectInvoke<TResult> (action);
445 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
447 return new FuncInvoke<TResult> (action);
450 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
452 return new FuncObjectInvoke<TResult> (action);
455 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
457 return new FuncTaskInvoke<TResult> (action);
460 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
462 return new FuncTaskObjectInvoke<TResult> (action);
465 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
467 return new FuncTaskInvoke<TResult, TNewResult> (action);
470 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
472 return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
475 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
477 return new ActionTasksInvoke (action, tasks);
480 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
482 return new FuncTasksInvoke<TResult> (action, tasks);
485 #region Used by WhenAny
487 public static TaskActionInvoker Create (Action<Task> action, Task[] tasks)
489 return new ActionTaskSelected (action, tasks);
492 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action, Task[] tasks)
494 return new FuncTaskSelected<TResult> (action, tasks);
499 public abstract Delegate Action { get; }
500 public abstract void Invoke (Task owner, object state, Task context);