// // TaskActionInvoker.cs // // Authors: // Marek Safar // // Copyright 2011 Xamarin Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // #if NET_4_0 using System.Threading; namespace System.Threading.Tasks { abstract class TaskActionInvoker { public static readonly TaskActionInvoker Empty = new EmptyTaskActionInvoker (); public static readonly TaskActionInvoker Promise = new EmptyTaskActionInvoker (); public static readonly TaskActionInvoker Delay = new DelayTaskInvoker (); sealed class EmptyTaskActionInvoker : TaskActionInvoker { public override Delegate Action { get { return null; } } public override void Invoke (Task owner, object state, Task context) { } } sealed class ActionInvoke : TaskActionInvoker { readonly Action action; public ActionInvoke (Action action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action (); } } sealed class ActionObjectInvoke : TaskActionInvoker { readonly Action action; public ActionObjectInvoke (Action action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action (state); } } sealed class ActionTaskInvoke : TaskActionInvoker { readonly Action action; public ActionTaskInvoke (Action action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action (owner); } } sealed class ActionTasksInvoke : TaskActionInvoker { readonly Action action; readonly Task[] tasks; public ActionTasksInvoke (Action action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { owner.TrySetExceptionObserved (); action (tasks); } } sealed class ActionTaskObjectInvoke : TaskActionInvoker { readonly Action action; public ActionTaskObjectInvoke (Action action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action (owner, state); } } sealed class ActionTaskObjectInvoke : TaskActionInvoker { readonly Action, object> action; public ActionTaskObjectInvoke (Action, object> action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action ((Task) owner, state); } } sealed class ActionTaskInvoke : TaskActionInvoker { readonly Action> action; public ActionTaskInvoke (Action> action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action ((Task) owner); } } sealed class ActionTaskSelected : TaskActionInvoker { readonly Action action; public ActionTaskSelected (Action action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { action (((Task)owner).Result); } } sealed class FuncInvoke : TaskActionInvoker { readonly Func action; public FuncInvoke (Func action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action (); } } sealed class FuncTaskInvoke : TaskActionInvoker { readonly Func action; public FuncTaskInvoke (Func action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action (owner); } } sealed class FuncTasksInvoke : TaskActionInvoker { readonly Func action; readonly Task[] tasks; public FuncTasksInvoke (Func action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { owner.TrySetExceptionObserved (); ((Task) context).Result = action (tasks); } } sealed class FuncTaskSelected : TaskActionInvoker { readonly Func action; public FuncTaskSelected (Func action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { var result = ((Task) owner).Result; ((Task) context).Result = action (result); } } sealed class FuncTaskInvoke : TaskActionInvoker { readonly Func, TNewResult> action; public FuncTaskInvoke (Func, TNewResult> action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action ((Task) owner); } } sealed class FuncObjectInvoke : TaskActionInvoker { readonly Func action; public FuncObjectInvoke (Func action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action (state); } } sealed class FuncTaskObjectInvoke : TaskActionInvoker { readonly Func action; public FuncTaskObjectInvoke (Func action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action (owner, state); } } sealed class FuncTaskObjectInvoke : TaskActionInvoker { readonly Func, object, TNewResult> action; public FuncTaskObjectInvoke (Func, object, TNewResult> action) { this.action = action; } public override Delegate Action { get { return action; } } public override void Invoke (Task owner, object state, Task context) { ((Task) context).Result = action ((Task) owner, state); } } sealed class DelayTaskInvoker : TaskActionInvoker { public override Delegate Action { get { return null; } } public override void Invoke (Task owner, object state, Task context) { var mre = new ManualResetEventSlim (); int timeout = (int) state; mre.Wait (timeout, context.CancellationToken); } } public static TaskActionInvoker Create (Action action) { return new ActionInvoke (action); } public static TaskActionInvoker Create (Action action) { return new ActionObjectInvoke (action); } public static TaskActionInvoker Create (Action action) { return new ActionTaskInvoke (action); } public static TaskActionInvoker Create (Action action) { return new ActionTaskObjectInvoke (action); } public static TaskActionInvoker Create (Action> action) { return new ActionTaskInvoke (action); } public static TaskActionInvoker Create (Action, object> action) { return new ActionTaskObjectInvoke (action); } public static TaskActionInvoker Create (Func action) { return new FuncInvoke (action); } public static TaskActionInvoker Create (Func action) { return new FuncObjectInvoke (action); } public static TaskActionInvoker Create (Func action) { return new FuncTaskInvoke (action); } public static TaskActionInvoker Create (Func action) { return new FuncTaskObjectInvoke (action); } public static TaskActionInvoker Create (Func, TNewResult> action) { return new FuncTaskInvoke (action); } public static TaskActionInvoker Create (Func, object, TNewResult> action) { return new FuncTaskObjectInvoke (action); } #region Used by ContinueWhenAll public static TaskActionInvoker Create (Action action, Task[] tasks) { return new ActionTasksInvoke (action, tasks); } public static TaskActionInvoker Create (Func action, Task[] tasks) { return new FuncTasksInvoke (action, tasks); } #endregion #region Used by ContinueWhenAny public static TaskActionInvoker CreateSelected (Action action) { return new ActionTaskSelected (action); } public static TaskActionInvoker CreateSelected (Func action) { return new FuncTaskSelected (action); } #endregion public abstract Delegate Action { get; } public abstract void Invoke (Task owner, object state, Task context); } } #endif