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 Promise = new EmptyTaskActionInvoker ();
39 public static readonly TaskActionInvoker Delay = new DelayTaskInvoker ();
41 sealed class EmptyTaskActionInvoker : TaskActionInvoker
43 public override Delegate Action {
49 public override void Invoke (Task owner, object state, Task context)
54 sealed class ActionInvoke : TaskActionInvoker
56 readonly Action action;
58 public ActionInvoke (Action action)
63 public override Delegate Action {
69 public override void Invoke (Task owner, object state, Task context)
75 sealed class ActionObjectInvoke : TaskActionInvoker
77 readonly Action<object> action;
79 public ActionObjectInvoke (Action<object> action)
84 public override Delegate Action {
90 public override void Invoke (Task owner, object state, Task context)
96 sealed class ActionTaskInvoke : TaskActionInvoker
98 readonly Action<Task> action;
100 public ActionTaskInvoke (Action<Task> action)
102 this.action = action;
105 public override Delegate Action {
111 public override void Invoke (Task owner, object state, Task context)
117 sealed class ActionTasksInvoke : TaskActionInvoker
119 readonly Action<Task[]> action;
120 readonly Task[] tasks;
122 public ActionTasksInvoke (Action<Task[]> action, Task[] tasks)
124 this.action = action;
128 public override Delegate Action {
134 public override void Invoke (Task owner, object state, Task context)
136 owner.TrySetExceptionObserved ();
141 sealed class ActionTaskObjectInvoke : TaskActionInvoker
143 readonly Action<Task, object> action;
145 public ActionTaskObjectInvoke (Action<Task, object> action)
147 this.action = action;
150 public override Delegate Action {
156 public override void Invoke (Task owner, object state, Task context)
158 action (owner, state);
162 sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker
164 readonly Action<Task<TResult>, object> action;
166 public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
168 this.action = action;
171 public override Delegate Action {
177 public override void Invoke (Task owner, object state, Task context)
179 action ((Task<TResult>) owner, state);
183 sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
185 readonly Action<Task<TResult>> action;
187 public ActionTaskInvoke (Action<Task<TResult>> action)
189 this.action = action;
192 public override Delegate Action {
198 public override void Invoke (Task owner, object state, Task context)
200 action ((Task<TResult>) owner);
204 sealed class ActionTaskSelected : TaskActionInvoker
206 readonly Action<Task> action;
208 public ActionTaskSelected (Action<Task> action)
210 this.action = action;
213 public override Delegate Action {
219 public override void Invoke (Task owner, object state, Task context)
221 action (((Task<Task>)owner).Result);
225 sealed class FuncInvoke<TResult> : TaskActionInvoker
227 readonly Func<TResult> action;
229 public FuncInvoke (Func<TResult> action)
231 this.action = action;
234 public override Delegate Action {
240 public override void Invoke (Task owner, object state, Task context)
242 ((Task<TResult>) context).Result = action ();
246 sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
248 readonly Func<Task, TResult> action;
250 public FuncTaskInvoke (Func<Task, TResult> action)
252 this.action = action;
255 public override Delegate Action {
261 public override void Invoke (Task owner, object state, Task context)
263 ((Task<TResult>) context).Result = action (owner);
267 sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
269 readonly Func<Task[], TResult> action;
270 readonly Task[] tasks;
272 public FuncTasksInvoke (Func<Task[], TResult> action, Task[] tasks)
274 this.action = action;
278 public override Delegate Action {
284 public override void Invoke (Task owner, object state, Task context)
286 owner.TrySetExceptionObserved ();
287 ((Task<TResult>) context).Result = action (tasks);
291 sealed class FuncTaskSelected<TResult> : TaskActionInvoker
293 readonly Func<Task, TResult> action;
295 public FuncTaskSelected (Func<Task, TResult> action)
297 this.action = action;
300 public override Delegate Action {
306 public override void Invoke (Task owner, object state, Task context)
308 var result = ((Task<Task>) owner).Result;
309 ((Task<TResult>) context).Result = action (result);
313 sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
315 readonly Func<Task<TResult>, TNewResult> action;
317 public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
319 this.action = action;
322 public override Delegate Action {
328 public override void Invoke (Task owner, object state, Task context)
330 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
334 sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
336 readonly Func<object, TResult> action;
338 public FuncObjectInvoke (Func<object, TResult> action)
340 this.action = action;
343 public override Delegate Action {
349 public override void Invoke (Task owner, object state, Task context)
351 ((Task<TResult>) context).Result = action (state);
355 sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
357 readonly Func<Task, object, TResult> action;
359 public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
361 this.action = action;
364 public override Delegate Action {
370 public override void Invoke (Task owner, object state, Task context)
372 ((Task<TResult>) context).Result = action (owner, state);
376 sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
378 readonly Func<Task<TResult>, object, TNewResult> action;
380 public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
382 this.action = action;
385 public override Delegate Action {
391 public override void Invoke (Task owner, object state, Task context)
393 ((Task<TNewResult>) context).Result = action ((Task<TResult>) owner, state);
397 sealed class DelayTaskInvoker : TaskActionInvoker
399 public override Delegate Action {
405 public override void Invoke (Task owner, object state, Task context)
407 var mre = new ManualResetEventSlim ();
408 int timeout = (int) state;
409 mre.Wait (timeout, context.CancellationToken);
413 public static TaskActionInvoker Create (Action action)
415 return new ActionInvoke (action);
418 public static TaskActionInvoker Create (Action<object> action)
420 return new ActionObjectInvoke (action);
423 public static TaskActionInvoker Create (Action<Task> action)
425 return new ActionTaskInvoke (action);
428 public static TaskActionInvoker Create (Action<Task, object> action)
430 return new ActionTaskObjectInvoke (action);
433 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
435 return new ActionTaskInvoke<TResult> (action);
438 public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
440 return new ActionTaskObjectInvoke<TResult> (action);
443 public static TaskActionInvoker Create<TResult> (Func<TResult> action)
445 return new FuncInvoke<TResult> (action);
448 public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
450 return new FuncObjectInvoke<TResult> (action);
453 public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
455 return new FuncTaskInvoke<TResult> (action);
458 public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
460 return new FuncTaskObjectInvoke<TResult> (action);
463 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
465 return new FuncTaskInvoke<TResult, TNewResult> (action);
468 public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
470 return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
473 #region Used by ContinueWhenAll
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);
487 #region Used by ContinueWhenAny
489 public static TaskActionInvoker CreateSelected (Action<Task> action)
491 return new ActionTaskSelected (action);
494 public static TaskActionInvoker CreateSelected<TResult> (Func<Task, TResult> action)
496 return new FuncTaskSelected<TResult> (action);
501 public abstract Delegate Action { get; }
502 public abstract void Invoke (Task owner, object state, Task context);