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;
294 public FuncTaskSelected (Func<Task, TResult> action)
296 this.action = action;
299 public override Delegate Action {
305 public override void Invoke (Task owner, object state, Task context)
307 var result = ((Task<Task>) owner).Result;
308 ((Task<TResult>) context).Result = action (result);
312 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
314 readonly Func<Task<TResult>, TNewResult> action;
316 public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
318 this.action = action;
321 public override Delegate Action {
327 public override void Invoke (Task owner, object state, Task context)
329 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
333 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
335 readonly Func<object, TResult> action;
337 public FuncObjectInvoke (Func<object, TResult> action)
339 this.action = action;
342 public override Delegate Action {
348 public override void Invoke (Task owner, object state, Task context)
350 ((Task<TResult>) context).Result = action (state);
354 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
356 readonly Func<Task, object, TResult> action;
358 public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
360 this.action = action;
363 public override Delegate Action {
369 public override void Invoke (Task owner, object state, Task context)
371 ((Task<TResult>) context).Result = action (owner, state);
375 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
377 readonly Func<Task<TResult>, object, TNewResult> action;
379 public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
381 this.action = action;
384 public override Delegate Action {
390 public override void Invoke (Task owner, object state, Task context)
392 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
396 sealed class DelayTaskInvoker : TaskActionInvoker
398 public override Delegate Action {
404 public override void Invoke (Task owner, object state, Task context)
406 var mre = new ManualResetEventSlim ();
407 int timeout = (int) state;
408 mre.Wait (timeout, context.CancellationToken);
412 public static TaskActionInvoker Create (Action action)
414 return new ActionInvoke (action);
417 public static TaskActionInvoker Create (Action<object> action)
419 return new ActionObjectInvoke (action);
422 public static TaskActionInvoker Create (Action<Task> action)
424 return new ActionTaskInvoke (action);
427 public static TaskActionInvoker Create (Action<Task, object> action)
429 return new ActionTaskObjectInvoke (action);
432 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
434 return new ActionTaskInvoke<TResult> (action);
437 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
439 return new ActionTaskObjectInvoke<TResult> (action);
442 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
444 return new FuncInvoke<TResult> (action);
447 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
449 return new FuncObjectInvoke<TResult> (action);
452 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
454 return new FuncTaskInvoke<TResult> (action);
457 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
459 return new FuncTaskObjectInvoke<TResult> (action);
462 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
464 return new FuncTaskInvoke<TResult, TNewResult> (action);
467 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
469 return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
472 #region Used by ContinueWhenAll
474 public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
476 return new ActionTasksInvoke (action, tasks);
479 public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
481 return new FuncTasksInvoke<TResult> (action, tasks);
486 #region Used by ContinueWhenAny
488 public static TaskActionInvoker CreateSelected (Action<Task> action)
490 return new ActionTaskSelected (action);
493 public static TaskActionInvoker CreateSelected<TResult> (Func<Task, TResult> action)
495 return new FuncTaskSelected<TResult> (action);
500 public abstract Delegate Action { get; }
501 public abstract void Invoke (Task owner, object state, Task context);