#if NET20 || NET30 || NET35 || !NET_4_6 using System.Diagnostics.Contracts; namespace System.Threading.Tasks { internal sealed class ContinuationTaskFromResultTask : Task, IContinuationTask { private Task _antecedent; public ContinuationTaskFromResultTask(Task antecedent, Delegate action, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : base(action, state, InternalCurrentIfAttached(creationOptions), default(CancellationToken), creationOptions, internalOptions, TaskScheduler.Default) { Contract.Requires(action is Action> || action is Action, object>, "Invalid delegate type in ContinuationTaskFromResultTask"); _antecedent = antecedent; CapturedContext = ExecutionContext.Capture(); } public Task Antecedent { get { return _antecedent; } } /// /// Evaluates the value selector of the Task which is passed in as an object and stores the result. /// internal override void InnerInvoke() { // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. var antecedent = _antecedent; Contract.Assert(antecedent != null, "No antecedent was set for the ContinuationTaskFromResultTask."); _antecedent = null; // Invoke the delegate Contract.Assert(Action != null); var action = Action as Action>; if (action != null) { action(antecedent); return; } var actionWithState = Action as Action, object>; if (actionWithState != null) { actionWithState(antecedent, State); return; } Contract.Assert(false, "Invalid Action in ContinuationTaskFromResultTask"); } } } #endif