Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / Tasks / TaskFactory.cs / 1305376 / TaskFactory.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// TaskFactory.cs
//
// [....]
//
// There are a plethora of common patterns for which Tasks are created. TaskFactory encodes
// these patterns into helper methods. These helpers also pick up default configuration settings
// applicable to the entire factory and configurable through its constructors.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Diagnostics.Contracts;
namespace System.Threading.Tasks
{
///
/// Provides support for creating and scheduling
/// Tasks .
///
///
///
/// There are many common patterns for which tasks are relevant. The
/// class encodes some of these patterns into methods that pick up default settings, which are
/// configurable through its constructors.
///
///
/// A default instance of is available through the
/// Task.Factory property.
///
///
[HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public class TaskFactory
{
// member variables
private CancellationToken m_defaultCancellationToken;
private TaskScheduler m_defaultScheduler;
private TaskCreationOptions m_defaultCreationOptions;
private TaskContinuationOptions m_defaultContinuationOptions;
private TaskScheduler DefaultScheduler
{
get
{
if (m_defaultScheduler == null) return TaskScheduler.Current;
else return m_defaultScheduler;
}
}
// sister method to above property -- avoids a TLS lookup
private TaskScheduler GetDefaultScheduler(Task currTask)
{
if (m_defaultScheduler != null) return m_defaultScheduler;
else if (currTask != null) return currTask.ExecutingTaskScheduler;
else return TaskScheduler.Default;
}
/* Constructors */
// ctor parameters provide defaults for the factory, which can be overridden by options provided to
// specific calls on the factory
///
/// Initializes a instance with the default configuration.
///
///
/// This constructor creates a instance with a default configuration. The
/// property is initialized to
/// TaskCreationOptions.None , the
/// property is initialized to TaskContinuationOptions.None ,
/// and the TaskScheduler property is
/// initialized to the current scheduler (see TaskScheduler.Current ).
///
public TaskFactory()
: this(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, null)
{
}
///
/// Initializes a instance with the specified configuration.
///
/// The default that will be assigned
/// to tasks created by this unless another CancellationToken is explicitly specified
/// while calling the factory methods.
///
/// This constructor creates a instance with a default configuration. The
/// property is initialized to
/// TaskCreationOptions.None , the
/// property is initialized to TaskContinuationOptions.None ,
/// and the TaskScheduler property is
/// initialized to the current scheduler (see TaskScheduler.Current ).
///
public TaskFactory(CancellationToken cancellationToken)
: this(cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
{
}
///
/// Initializes a instance with the specified configuration.
///
///
/// The
/// TaskScheduler to use to schedule any tasks created with this TaskFactory. A null value
/// indicates that the current TaskScheduler should be used.
///
///
/// With this constructor, the
/// property is initialized to
/// TaskCreationOptions.None , the
/// property is initialized to TaskContinuationOptions.None ,
/// and the TaskScheduler property is
/// initialized to , unless it's null, in which case the property is
/// initialized to the current scheduler (see TaskScheduler.Current ).
///
public TaskFactory(TaskScheduler scheduler) // null means to use TaskScheduler.Current
: this(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
{
}
///
/// Initializes a instance with the specified configuration.
///
///
/// The default
/// TaskCreationOptions to use when creating tasks with this TaskFactory.
///
///
/// The default
/// TaskContinuationOptions to use when creating continuation tasks with this TaskFactory.
///
///
/// The exception that is thrown when the
/// argument or the
/// argument specifies an invalid value.
///
///
/// With this constructor, the
/// property is initialized to ,
/// the
/// property is initialized to , and the TaskScheduler property is initialized to the
/// current scheduler (see TaskScheduler.Current ).
///
public TaskFactory(TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
: this(CancellationToken.None, creationOptions, continuationOptions, null)
{
}
///
/// Initializes a instance with the specified configuration.
///
/// The default that will be assigned
/// to tasks created by this unless another CancellationToken is explicitly specified
/// while calling the factory methods.
///
/// The default
/// TaskCreationOptions to use when creating tasks with this TaskFactory.
///
///
/// The default
/// TaskContinuationOptions to use when creating continuation tasks with this TaskFactory.
///
///
/// The default
/// TaskScheduler to use to schedule any Tasks created with this TaskFactory. A null value
/// indicates that TaskScheduler.Current should be used.
///
///
/// The exception that is thrown when the
/// argument or the
/// argumentspecifies an invalid value.
///
///
/// With this constructor, the
/// property is initialized to ,
/// the
/// property is initialized to , and the TaskScheduler property is initialized to
/// , unless it's null, in which case the property is initialized to the
/// current scheduler (see TaskScheduler.Current ).
///
public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
m_defaultCancellationToken = cancellationToken;
m_defaultScheduler = scheduler;
m_defaultCreationOptions = creationOptions;
m_defaultContinuationOptions = continuationOptions;
CheckCreationOptions(m_defaultCreationOptions);
CheckMultiTaskContinuationOptions(m_defaultContinuationOptions);
}
internal static void CheckCreationOptions(TaskCreationOptions creationOptions)
{
// Check for validity of options
if ((creationOptions &
~(TaskCreationOptions.AttachedToParent |
TaskCreationOptions.LongRunning |
TaskCreationOptions.PreferFairness)) != 0)
{
throw new ArgumentOutOfRangeException("creationOptions");
}
}
/* Properties */
///
/// Gets the default CancellationToken of this
/// TaskFactory.
///
///
/// This property returns the default that will be assigned to all
/// tasks created by this factory unless another CancellationToken value is explicitly specified
/// during the call to the factory methods.
///
public CancellationToken CancellationToken { get { return m_defaultCancellationToken; } }
///
/// Gets the TaskScheduler of this
/// TaskFactory.
///
///
/// This property returns the default scheduler for this factory. It will be used to schedule all
/// tasks unless another scheduler is explicitly specified during calls to this factory's methods.
/// If null, TaskScheduler.Current
/// will be used.
///
public TaskScheduler Scheduler { get { return m_defaultScheduler; } }
///
/// Gets the TaskCreationOptions
/// value of this TaskFactory.
///
///
/// This property returns the default creation options for this factory. They will be used to create all
/// tasks unless other options are explicitly specified during calls to this factory's methods.
///
public TaskCreationOptions CreationOptions { get { return m_defaultCreationOptions; } }
///
/// Gets the TaskContinuationOptions
/// value of this TaskFactory.
///
///
/// This property returns the default continuation options for this factory. They will be used to create
/// all continuation tasks unless other options are explicitly specified during calls to this factory's methods.
///
public TaskContinuationOptions ContinuationOptions { get { return m_defaultContinuationOptions; } }
//
// StartNew methods
//
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors
/// and then calling
/// Start to schedule it for execution. However,
/// unless creation and scheduling must be separated, StartNew is the recommended
/// approach for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask),
m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// The that will be assigned to the new task.
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors
/// and then calling
/// Start to schedule it for execution. However,
/// unless creation and scheduling must be separated, StartNew is the recommended
/// approach for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, null, cancellationToken, GetDefaultScheduler(currTask),
m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// Task.
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask), creationOptions,
InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// The that will be assigned to the new
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// Task.
/// The TaskScheduler
/// that is used to schedule the created Task .
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(Task.InternalCurrent, action, null, cancellationToken, scheduler, creationOptions,
InternalTaskOptions.None, ref stackMark);
}
// Internal version includes InternalTaskOptions for Parallel.Invoke() support.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
internal Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(Task.InternalCurrent, action, null, cancellationToken, scheduler, creationOptions, internalOptions, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// An object containing data to be used by the
/// delegate.
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, Object state)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// An object containing data to be used by the
/// delegate.
/// The that will be assigned to the new
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, Object state, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, cancellationToken, GetDefaultScheduler(currTask),
m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// An object containing data to be used by the
/// delegate.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// Task.
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, Object state, TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
creationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a Task .
///
/// The action delegate to execute asynchronously.
/// An object containing data to be used by the
/// delegate.
/// The that will be assigned to the new task.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// Task.
/// The TaskScheduler
/// that is used to schedule the created Task .
/// The started Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
/// then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Action action, Object state, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(Task.InternalCurrent, action, state, cancellationToken, scheduler,
creationOptions, InternalTaskOptions.None, ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// The started .
/// The exception that is thrown when the
/// argument is null.
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, m_defaultCancellationToken,
m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// The that will be assigned to the new
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, cancellationToken,
m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// .
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, m_defaultCancellationToken,
creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// The that will be assigned to the new task.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// .
/// The TaskScheduler
/// that is used to schedule the created
/// Task{TResult} .
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.StartNew(Task.InternalCurrent, function, cancellationToken,
creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// An object containing data to be used by the
/// delegate.
/// The started .
/// The exception that is thrown when the
/// argument is null.
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, Object state)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, state, m_defaultCancellationToken,
m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// An object containing data to be used by the
/// delegate.
/// The that will be assigned to the new
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, Object state, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, state, cancellationToken,
m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// An object containing data to be used by the
/// delegate.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// .
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, Object state, TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task currTask = Task.InternalCurrent;
return Task.StartNew(currTask, function, state, m_defaultCancellationToken,
creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
}
///
/// Creates and starts a .
///
/// The type of the result available through the
/// Task .
///
/// A function delegate that returns the future result to be available through
/// the .
/// An object containing data to be used by the
/// delegate.
/// The that will be assigned to the new task.
/// A TaskCreationOptions value that controls the behavior of the
/// created
/// .
/// The TaskScheduler
/// that is used to schedule the created
/// Task{TResult} .
/// The started .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// Calling StartNew is functionally equivalent to creating a using one
/// of its constructors and then calling
/// Start to schedule it for execution.
/// However, unless creation and scheduling must be separated, StartNew is the recommended approach
/// for both simplicity and performance.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task StartNew(Func function, Object state, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.StartNew(Task.InternalCurrent, function, state, cancellationToken,
creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
}
//
// FromAsync methods
//
// Common core logic for FromAsync calls. This minimizes the chance of "drift" between overload implementations.
private static void FromAsyncCoreLogic(IAsyncResult iar, Action endMethod, TaskCompletionSource tcs)
{
Exception ex = null;
OperationCanceledException oce = null;
try { endMethod(iar); }
catch (OperationCanceledException _oce) { oce = _oce; }
catch (Exception e) { ex = e; }
finally
{
if (oce != null) tcs.TrySetCanceled();
else if (ex != null)
{
bool bWonSetException = tcs.TrySetException(ex);
if (bWonSetException && ex is ThreadAbortException)
{
tcs.Task.m_contingentProperties.m_exceptionsHolder.MarkAsHandled(false);
}
}
else tcs.TrySetResult(null);
}
}
///
/// Creates a Task that executes an end method action
/// when a specified IAsyncResult completes.
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The action delegate that processes the completed .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// A Task that represents the asynchronous
/// operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult,
Action endMethod)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return FromAsync(asyncResult, endMethod, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
}
///
/// Creates a Task that executes an end method action
/// when a specified IAsyncResult completes.
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The action delegate that processes the completed .
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// A Task that represents the asynchronous
/// operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult,
Action endMethod,
TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return FromAsync(asyncResult, endMethod, creationOptions, DefaultScheduler, ref stackMark);
}
///
/// Creates a Task that executes an end method action
/// when a specified IAsyncResult completes.
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The action delegate that processes the completed .
/// The TaskScheduler
/// that is used to schedule the task that executes the end method.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// A Task that represents the asynchronous
/// operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult,
Action endMethod,
TaskCreationOptions creationOptions,
TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return FromAsync(asyncResult, endMethod, creationOptions, scheduler, ref stackMark);
}
// private version that supports StackCrawlMark.
private Task FromAsync(
IAsyncResult asyncResult,
Action endMethod,
TaskCreationOptions creationOptions,
TaskScheduler scheduler,
ref StackCrawlMark stackMark)
{
if (asyncResult == null)
throw new ArgumentNullException("asyncResult");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
if (scheduler == null)
throw new ArgumentNullException("scheduler");
CheckFromAsyncOptions(creationOptions, false);
TaskCompletionSource tcs = new TaskCompletionSource(null, creationOptions);
// Just specify this task as detached. No matter what happens, we want endMethod
// to be called -- even if the parent is canceled.
Task t = new Task(delegate
{
FromAsyncCoreLogic(asyncResult, endMethod, tcs);
},
(object)null, Task.InternalCurrent,
CancellationToken.None, TaskCreationOptions.None, InternalTaskOptions.None, null, ref stackMark);
if (asyncResult.IsCompleted)
{
try { t.RunSynchronously(scheduler); }
catch (Exception e) { tcs.TrySetException(e); } // catch and log any scheduler exceptions
}
else
{
ThreadPool.RegisterWaitForSingleObject(
asyncResult.AsyncWaitHandle,
delegate
{
try { t.RunSynchronously(scheduler); }
catch (Exception e) { tcs.TrySetException(e); } // catch and log any scheduler exceptions
},
null,
Timeout.Infinite,
true);
}
return tcs.Task;
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
object state)
{
return FromAsync(beginMethod, endMethod, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod, object state, TaskCreationOptions creationOptions)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
CheckFromAsyncOptions(creationOptions, true);
TaskCompletionSource tcs = new TaskCompletionSource(state, creationOptions);
try
{
beginMethod(iar =>
{
FromAsyncCoreLogic(iar, endMethod, tcs);
}, state);
}
catch
{
// Make sure we don't leave tcs "dangling".
tcs.TrySetResult(null);
throw;
}
return tcs.Task;
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1,
object state)
{
return FromAsync(beginMethod, endMethod, arg1, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1, object state, TaskCreationOptions creationOptions)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
CheckFromAsyncOptions(creationOptions, true);
TaskCompletionSource tcs = new TaskCompletionSource(state, creationOptions);
try
{
beginMethod(arg1, iar =>
{
FromAsyncCoreLogic(iar, endMethod, tcs);
}, state);
}
catch
{
// Make sure we don't leave tcs "dangling".
tcs.TrySetResult(null);
throw;
}
return tcs.Task;
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The type of the second argument passed to
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1, TArg2 arg2, object state)
{
return FromAsync(beginMethod, endMethod, arg1, arg2, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The type of the second argument passed to
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
CheckFromAsyncOptions(creationOptions, true);
TaskCompletionSource tcs = new TaskCompletionSource(state, creationOptions);
try
{
beginMethod(arg1, arg2, iar =>
{
FromAsyncCoreLogic(iar, endMethod, tcs);
}, state);
}
catch
{
// Make sure we don't leave tcs "dangling".
tcs.TrySetResult(null);
throw;
}
return tcs.Task;
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the third argument passed to
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The third argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
{
return FromAsync(beginMethod, endMethod, arg1, arg2, arg3, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of begin
/// and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the
/// delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the third argument passed to
/// delegate.
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The third argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that represents the
/// asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Action endMethod,
TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
CheckFromAsyncOptions(creationOptions, true);
TaskCompletionSource tcs = new TaskCompletionSource(state, creationOptions);
try
{
beginMethod(arg1, arg2, arg3, iar =>
{
FromAsyncCoreLogic(iar, endMethod, tcs);
}, state);
}
catch
{
// Make sure we don't leave tcs "dangling".
tcs.TrySetResult(null);
throw;
}
return tcs.Task;
}
//
// Additional FromAsync() overloads used for inferencing convenience
//
///
/// Creates a Task that executes an end
/// method function when a specified IAsyncResult completes.
///
/// The type of the result available through the
/// Task .
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The function delegate that processes the completed .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// A Task that represents the
/// asynchronous operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult, Func endMethod)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return TaskFactory.FromAsyncImpl(asyncResult, endMethod, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
}
///
/// Creates a Task that executes an end
/// method function when a specified IAsyncResult completes.
///
/// The type of the result available through the
/// Task .
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The function delegate that processes the completed .
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// A Task that represents the
/// asynchronous operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult, Func endMethod, TaskCreationOptions creationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return TaskFactory.FromAsyncImpl(asyncResult, endMethod, creationOptions, DefaultScheduler, ref stackMark);
}
///
/// Creates a Task that executes an end
/// method function when a specified IAsyncResult completes.
///
/// The type of the result available through the
/// Task .
///
/// The IAsyncResult whose completion should trigger the processing of the
/// .
/// The function delegate that processes the completed .
/// The TaskScheduler
/// that is used to schedule the task that executes the end method.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// A Task that represents the
/// asynchronous operation.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task FromAsync(
IAsyncResult asyncResult, Func endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return TaskFactory.FromAsyncImpl(asyncResult, endMethod, creationOptions, scheduler, ref stackMark);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, object state)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, object state, TaskCreationOptions creationOptions)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, state, creationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, object state)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, object state, TaskCreationOptions creationOptions)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, state, creationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, TArg2 arg2, object state)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, arg2, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, arg2, state, creationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the third argument passed to
/// delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The third argument passed to the
/// delegate.
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, arg2, arg3, state, m_defaultCreationOptions);
}
///
/// Creates a Task that represents a pair of
/// begin and end methods that conform to the Asynchronous Programming Model pattern.
///
/// The type of the first argument passed to the delegate.
/// The type of the second argument passed to
/// delegate.
/// The type of the third argument passed to
/// delegate.
/// The type of the result available through the
/// Task .
///
/// The delegate that begins the asynchronous operation.
/// The delegate that ends the asynchronous operation.
/// The first argument passed to the
/// delegate.
/// The second argument passed to the
/// delegate.
/// The third argument passed to the
/// delegate.
/// The TaskCreationOptions value that controls the behavior of the
/// created Task .
/// An object containing data to be used by the
/// delegate.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument specifies an invalid TaskCreationOptions
/// value.
/// The created Task that
/// represents the asynchronous operation.
///
/// This method throws any exceptions thrown by the .
///
public Task FromAsync(
Func beginMethod,
Func endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
{
return TaskFactory.FromAsyncImpl(beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
}
///
/// Check validity of options passed to FromAsync method
///
/// The options to be validated.
/// determines type of FromAsync method that called this method
internal static void CheckFromAsyncOptions(TaskCreationOptions creationOptions, bool hasBeginMethod)
{
if (hasBeginMethod)
{
// Options detected here cause exceptions in FromAsync methods that take beginMethod as a parameter
if ((creationOptions & TaskCreationOptions.LongRunning) != 0)
throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_LongRunning"));
if ((creationOptions & TaskCreationOptions.PreferFairness) != 0)
throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_PreferFairness"));
}
// Check for general validity of options
if ((creationOptions &
~(TaskCreationOptions.AttachedToParent |
TaskCreationOptions.PreferFairness |
TaskCreationOptions.LongRunning)) != 0)
{
throw new ArgumentOutOfRangeException("creationOptions");
}
}
//
// ContinueWhenAll methods
//
// Performs some logic common to all ContinueWhenAll() overloads
// Returns the Task off of which to continue.
internal static Task CommonCWAllLogic(Task[] tasksCopy)
{
// tcs will be "fired" when final task completes
// We want tcs.Task to be DetachedFromParent.
// -- If rval gets directly canceled, we don't want tcs.Task recorded as a child of Task.InternalCurrent,
// because Task.InternalCurrent will then not be able to complete.
// -- If Task.InternalCurrent gets canceled, tcs.Task would never know about it. Again, best if it
// is not recorded as a child of Task.InternalCurrent.
TaskCompletionSource tcs = new TaskCompletionSource();
// intermediate continuation tasks will decrement tasksLeft
int tasksLeft = tasksCopy.Length;
Action whenComplete = delegate(Task completedTask)
{
if (Interlocked.Decrement(ref tasksLeft) == 0) tcs.TrySetResult(true);
};
for (int i = 0; i < tasksCopy.Length; i++)
{
if (tasksCopy[i].IsCompleted) whenComplete(tasksCopy[i]); // Short-circuit the completion action, if possible
else tasksCopy[i].AddCompletionAction(whenComplete); // simple completion action
}
return tcs.Task;
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in
/// the array have completed.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action continuationAction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in
/// the array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action continuationAction, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in the array have completed.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action continuationAction, TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in the array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action continuationAction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// a private version that supports StackCrawlMark
private static Task ContinueWhenAll(Task[] tasks, Action continuationAction, TaskContinuationOptions continuationOptions,
CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
//check arguments
CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) throw new ArgumentNullException("tasks");
if (continuationAction == null) throw new ArgumentNullException("continuationAction");
if (scheduler == null) throw new ArgumentNullException("scheduler");
// Check the tasks array and make a defensive copy
Task[] tasksCopy = CheckMultiContinuationTasksAndCopy(tasks);
// Bail early if cancellation has been requested.
if (cancellationToken.IsCancellationRequested)
{
return CreateCanceledTask(continuationOptions);
}
// Perform some common ContinueWhenAll() setup actions
Task starter = CommonCWAllLogic(tasksCopy);
// Preserve continuationOptions for this task, which is returned to the user.
Task rval = starter.ContinueWith(finishedTask => continuationAction(tasksCopy), scheduler,
cancellationToken, continuationOptions, ref stackMark);
return rval;
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in
/// the array have completed.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action[]> continuationAction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in
/// the array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action[]> continuationAction,
CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in the array have completed.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action[]> continuationAction,
TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The action delegate to execute when all tasks in the array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action[]> continuationAction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// a private version that supports StackCrawlMark
private static Task ContinueWhenAll(Task[] tasks, Action[]> continuationAction,
TaskContinuationOptions continuationOptions, CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
//check arguments
CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) throw new ArgumentNullException("tasks");
if (continuationAction == null) throw new ArgumentNullException("continuationAction");
if (scheduler == null) throw new ArgumentNullException("scheduler");
// Check the tasks array and make a defensive copy
Task[] tasksCopy = CheckMultiContinuationTasksAndCopy(tasks);
// Bail early if cancellation has been requested.
if (cancellationToken.IsCancellationRequested)
{
return CreateCanceledTask(continuationOptions);
}
// Perform some common ContinueWhenAll() setup actions
Task starter = CommonCWAllLogic(tasksCopy);
// Preserve continuationOptions for this task, which is returned to the user.
Task rval = starter.ContinueWith(finishedTask => continuationAction(tasksCopy), scheduler,
cancellationToken, continuationOptions, ref stackMark);
return rval;
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func continuationFunction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func continuationFunction, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func continuationFunction, TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func continuationFunction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// a private version that supports StackCrawlMark
private Task ContinueWhenAll(Task[] tasks, Func continuationFunction, TaskContinuationOptions continuationOptions,
CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
// Delegate to TaskFactory
return TaskFactory.ContinueWhenAll(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func[], TResult> continuationFunction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func[], TResult> continuationFunction,
CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func[], TResult> continuationFunction,
TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of a set of provided Tasks.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue.
/// The function delegate to execute when all tasks in the
/// array have completed.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAll.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Func[], TResult> continuationFunction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAll(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// a private version that supports StackCrawlMark
private Task ContinueWhenAll(Task[] tasks, Func[], TResult> continuationFunction,
TaskContinuationOptions continuationOptions,CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
// Delegate to TaskFactory
return TaskFactory.ContinueWhenAll(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// Utility method to abstract some common logic to a single definition.
// Used by ContinueWhenAll/Any to bail out early on a pre-canceled token.
private static Task CreateCanceledTask(TaskContinuationOptions continuationOptions)
{
InternalTaskOptions dontcare;
TaskCreationOptions tco;
Task.CreationOptionsFromContinuationOptions(continuationOptions, out tco, out dontcare);
return new Task(true, tco);
}
//
// ContinueWhenAny methods
//
// Common ContinueWhenAny logic
// Returns Task off of which to create ultimate continuation task
internal static Task CommonCWAnyLogic(Task[] tasksCopy)
{
// tcs will be "fired" when the first task completes
TaskCompletionSource tcs = new TaskCompletionSource();
// The first task to complete will record itself as the Result of trs/starter.
Action whenComplete = delegate(Task t)
{
tcs.TrySetResult(t);
};
// At the completion of each task, fire whenComplete.
for (int i = 0; i < tasksCopy.Length; i++)
{
if (tcs.Task.IsCompleted) break; // Don't launch any more continuation tasks if trs has completed.
// Shortcut if a task has already completed.
if (tasksCopy[i].IsCompleted)
{
// Short-circuit the creation of a completion task.
whenComplete(tasksCopy[i]);
// We've found a winner. No need to create any more completion tasks.
break;
}
else tasksCopy[i].AddCompletionAction(whenComplete);
}
return tcs.Task;
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The array of tasks from which to continue when one task completes.
/// The action delegate to execute when one task in the array completes.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action continuationAction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The array of tasks from which to continue when one task completes.
/// The action delegate to execute when one task in the array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action continuationAction, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The array of tasks from which to continue when one task completes.
/// The action delegate to execute when one task in the array completes.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action continuationAction, TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The array of tasks from which to continue when one task completes.
/// The action delegate to execute when one task in the array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation Task .
/// The new continuation Task .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action continuationAction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// a private version that supports StackCrawlMark
private Task ContinueWhenAny(Task[] tasks, Action continuationAction, TaskContinuationOptions continuationOptions,
CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
// Check arguments
CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) throw new ArgumentNullException("tasks");
if (continuationAction == null) throw new ArgumentNullException("continuationAction");
if (scheduler == null) throw new ArgumentNullException("scheduler");
// Check the tasks array and make a defensive copy
Task[] tasksCopy = CheckMultiContinuationTasksAndCopy(tasks);
// Bail early if cancellation has been requested.
if (cancellationToken.IsCancellationRequested)
{
return CreateCanceledTask(continuationOptions);
}
// Perform common ContinueWithAny() setup logic
Task starter = CommonCWAnyLogic(tasksCopy);
// returned continuation task, fired when starter completes
Task rval = starter.ContinueWith(completedTask => continuationAction(completedTask.Result), scheduler,
cancellationToken, continuationOptions, ref stackMark);
return rval;
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func continuationFunction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func continuationFunction, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func continuationFunction, TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func continuationFunction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// private version that supports StackCrawlMark
private Task ContinueWhenAny(Task[] tasks, Func continuationFunction, TaskContinuationOptions continuationOptions,
CancellationToken cancellationToken, TaskScheduler scheduler, ref StackCrawlMark stackMark)
{
// Delegate to TaskFactory
return TaskFactory.ContinueWhenAny(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func, TResult> continuationFunction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func, TResult> continuationFunction,
CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func, TResult> continuationFunction,
TaskContinuationOptions continuationOptions)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
///
/// Creates a continuation Task
/// that will be started upon the completion of any Task in the provided set.
///
/// The type of the result that is returned by the
/// delegate and associated with the created .
/// The type of the result of the antecedent .
/// The array of tasks from which to continue when one task completes.
/// The function delegate to execute when one task in the
/// array completes.
/// The CancellationToken
/// that will be assigned to the new continuation task.
/// The
/// TaskContinuationOptions value that controls the behavior of
/// the created continuation Task .
/// The TaskScheduler
/// that is used to schedule the created continuation .
/// The new continuation .
/// The exception that is thrown when the
/// array is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// argument is null.
/// The exception that is thrown when the
/// array contains a null value.
/// The exception that is thrown when the
/// array is empty.
/// The exception that is thrown when the
/// argument specifies an invalid TaskContinuationOptions
/// value.
/// The exception that is thrown when one
/// of the elements in the array has been disposed.
/// The provided CancellationToken
/// has already been disposed.
///
///
/// The NotOn* and OnlyOn* TaskContinuationOptions ,
/// which constrain for which TaskStatus states a continuation
/// will be executed, are illegal with ContinueWhenAny.
///
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Func, TResult> continuationFunction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return ContinueWhenAny(tasks, continuationFunction, continuationOptions, cancellationToken, scheduler, ref stackMark);
}
// private version that supports StackCrawlMark
private Task ContinueWhenAny(Task[] tasks, Func