Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

506 lines
11 KiB
C#

//
// TaskActionInvoker.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// 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<object> action;
public ActionObjectInvoke (Action<object> 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<Task> action;
public ActionTaskInvoke (Action<Task> 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<Task[]> action;
readonly Task[] tasks;
public ActionTasksInvoke (Action<Task[]> 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<Task, object> action;
public ActionTaskObjectInvoke (Action<Task, object> 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<TResult> : TaskActionInvoker
{
readonly Action<Task<TResult>, object> action;
public ActionTaskObjectInvoke (Action<Task<TResult>, object> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
action ((Task<TResult>) owner, state);
}
}
sealed class ActionTaskInvoke<TResult> : TaskActionInvoker
{
readonly Action<Task<TResult>> action;
public ActionTaskInvoke (Action<Task<TResult>> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
action ((Task<TResult>) owner);
}
}
sealed class ActionTaskSelected : TaskActionInvoker
{
readonly Action<Task> action;
public ActionTaskSelected (Action<Task> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
action (((Task<Task>)owner).Result);
}
}
sealed class FuncInvoke<TResult> : TaskActionInvoker
{
readonly Func<TResult> action;
public FuncInvoke (Func<TResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TResult>) context).Result = action ();
}
}
sealed class FuncTaskInvoke<TResult> : TaskActionInvoker
{
readonly Func<Task, TResult> action;
public FuncTaskInvoke (Func<Task, TResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TResult>) context).Result = action (owner);
}
}
sealed class FuncTasksInvoke<TResult> : TaskActionInvoker
{
readonly Func<Task[], TResult> action;
readonly Task[] tasks;
public FuncTasksInvoke (Func<Task[], TResult> 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<TResult>) context).Result = action (tasks);
}
}
sealed class FuncTaskSelected<TResult> : TaskActionInvoker
{
readonly Func<Task, TResult> action;
public FuncTaskSelected (Func<Task, TResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
var result = ((Task<Task>) owner).Result;
((Task<TResult>) context).Result = action (result);
}
}
sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker
{
readonly Func<Task<TResult>, TNewResult> action;
public FuncTaskInvoke (Func<Task<TResult>, TNewResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TNewResult>) context).Result = action ((Task<TResult>) owner);
}
}
sealed class FuncObjectInvoke<TResult> : TaskActionInvoker
{
readonly Func<object, TResult> action;
public FuncObjectInvoke (Func<object, TResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TResult>) context).Result = action (state);
}
}
sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker
{
readonly Func<Task, object, TResult> action;
public FuncTaskObjectInvoke (Func<Task, object, TResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TResult>) context).Result = action (owner, state);
}
}
sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker
{
readonly Func<Task<TResult>, object, TNewResult> action;
public FuncTaskObjectInvoke (Func<Task<TResult>, object, TNewResult> action)
{
this.action = action;
}
public override Delegate Action {
get {
return action;
}
}
public override void Invoke (Task owner, object state, Task context)
{
((Task<TNewResult>) context).Result = action ((Task<TResult>) 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<object> action)
{
return new ActionObjectInvoke (action);
}
public static TaskActionInvoker Create (Action<Task> action)
{
return new ActionTaskInvoke (action);
}
public static TaskActionInvoker Create (Action<Task, object> action)
{
return new ActionTaskObjectInvoke (action);
}
public static TaskActionInvoker Create<TResult> (Action<Task<TResult>> action)
{
return new ActionTaskInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult> (Action<Task<TResult>, object> action)
{
return new ActionTaskObjectInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult> (Func<TResult> action)
{
return new FuncInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult> (Func<object, TResult> action)
{
return new FuncObjectInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult> (Func<Task, TResult> action)
{
return new FuncTaskInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult> (Func<Task, object, TResult> action)
{
return new FuncTaskObjectInvoke<TResult> (action);
}
public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, TNewResult> action)
{
return new FuncTaskInvoke<TResult, TNewResult> (action);
}
public static TaskActionInvoker Create<TResult, TNewResult> (Func<Task<TResult>, object, TNewResult> action)
{
return new FuncTaskObjectInvoke<TResult, TNewResult> (action);
}
#region Used by ContinueWhenAll
public static TaskActionInvoker Create (Action<Task[]> action, Task[] tasks)
{
return new ActionTasksInvoke (action, tasks);
}
public static TaskActionInvoker Create<TResult> (Func<Task[], TResult> action, Task[] tasks)
{
return new FuncTasksInvoke<TResult> (action, tasks);
}
#endregion
#region Used by ContinueWhenAny
public static TaskActionInvoker CreateSelected (Action<Task> action)
{
return new ActionTaskSelected (action);
}
public static TaskActionInvoker CreateSelected<TResult> (Func<Task, TResult> action)
{
return new FuncTaskSelected<TResult> (action);
}
#endregion
public abstract Delegate Action { get; }
public abstract void Invoke (Task owner, object state, Task context);
}
}
#endif