diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
commit | a56e30c8d33048216567753d9d3fefc2152af8ac (patch) | |
tree | 7e5d979695fc4a431740982eb1cfecc2898b23a5 /src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs | |
parent | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (diff) | |
download | coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.gz coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.bz2 coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.zip |
Imported Upstream version 2.0.0.11353upstream/2.0.0.11353
Diffstat (limited to 'src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs')
-rw-r--r-- | src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs index 89ba2988ca..e193d0e4e2 100644 --- a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs +++ b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs @@ -40,30 +40,20 @@ namespace System.Threading.Tasks public class TaskFactory { // member variables - private CancellationToken m_defaultCancellationToken; - private TaskScheduler m_defaultScheduler; - private TaskCreationOptions m_defaultCreationOptions; - private TaskContinuationOptions m_defaultContinuationOptions; + private readonly CancellationToken m_defaultCancellationToken; + private readonly TaskScheduler m_defaultScheduler; + private readonly TaskCreationOptions m_defaultCreationOptions; + private readonly TaskContinuationOptions m_defaultContinuationOptions; - - private TaskScheduler DefaultScheduler - { - get - { - if (m_defaultScheduler == null) return TaskScheduler.Current; - else return m_defaultScheduler; - } - } + private TaskScheduler DefaultScheduler => m_defaultScheduler ?? TaskScheduler.Current; // 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) - && ((currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0) - ) - return currTask.ExecutingTaskScheduler; - else return TaskScheduler.Default; + return + m_defaultScheduler ?? + (currTask != null && (currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0 ? currTask.ExecutingTaskScheduler : + TaskScheduler.Default); } /* Constructors */ @@ -1528,9 +1518,9 @@ namespace System.Threading.Tasks { // Options detected here cause exceptions in FromAsync methods that take beginMethod as a parameter if ((creationOptions & TaskCreationOptions.LongRunning) != 0) - throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_LongRunning")); + throw new ArgumentOutOfRangeException(nameof(creationOptions), SR.Task_FromAsync_LongRunning); if ((creationOptions & TaskCreationOptions.PreferFairness) != 0) - throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_PreferFairness")); + throw new ArgumentOutOfRangeException(nameof(creationOptions), SR.Task_FromAsync_PreferFairness); } // Check for general validity of options @@ -2325,7 +2315,7 @@ namespace System.Threading.Tasks { Contract.Requires(tasks != null, "Expected non-null collection of tasks"); _tasks = tasks; - + if (AsyncCausalityTracer.LoggingOn) AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAny", 0); @@ -2337,7 +2327,8 @@ namespace System.Threading.Tasks public void Invoke(Task completingTask) { - if (Interlocked.CompareExchange(ref m_firstTaskAlreadyCompleted, 1, 0) == 0) + if (m_firstTaskAlreadyCompleted == 0 && + Interlocked.Exchange(ref m_firstTaskAlreadyCompleted, 1) == 0) { if (AsyncCausalityTracer.LoggingOn) { @@ -2367,7 +2358,6 @@ namespace System.Threading.Tasks !task.IsCompleted) task.RemoveContinuation(this); } _tasks = null; - } } @@ -2382,17 +2372,18 @@ namespace System.Threading.Tasks { Contract.Requires(tasks != null); - // Create a promise task to be returned to the user + // Create a promise task to be returned to the user. + // (If this logic ever changes, also update CommonCWAnyLogicCleanup.) var promise = new CompleteOnInvokePromise(tasks); // At the completion of any of the tasks, complete the promise. bool checkArgsOnly = false; int numTasks = tasks.Count; - for(int i=0; i<numTasks; i++) + for (int i = 0; i < numTasks; i++) { var task = tasks[i]; - if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); + if (task == null) throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks)); if (checkArgsOnly) continue; @@ -2430,6 +2421,17 @@ namespace System.Threading.Tasks return promise; } + /// <summary> + /// Cleans up the operations performed by CommonCWAnyLogic in a case where + /// the created continuation task is being discarded. + /// </summary> + /// <param name="continuation">The task returned from CommonCWAnyLogic.</param> + internal static void CommonCWAnyLogicCleanup(Task<Task> continuation) + { + // Force cleanup of the promise (e.g. removing continuations from each + // constituent task), by completing the promise with any value. + ((CompleteOnInvokePromise)continuation).Invoke(null); + } /// <summary> /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see> @@ -2663,7 +2665,7 @@ namespace System.Threading.Tasks if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); - return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null,continuationOptions, m_defaultCancellationToken, DefaultScheduler); + return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler); } /// <summary> @@ -2775,7 +2777,7 @@ namespace System.Threading.Tasks if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction)); Contract.EndContractBlock(); - return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler); + return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler); } /// <summary> @@ -3018,7 +3020,7 @@ namespace System.Threading.Tasks if (tasks == null) throw new ArgumentNullException(nameof(tasks)); if (tasks.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks)); + throw new ArgumentException(SR.Task_MultiTaskContinuation_EmptyTaskList, nameof(tasks)); Contract.EndContractBlock(); Task[] tasksCopy = new Task[tasks.Length]; @@ -3027,7 +3029,7 @@ namespace System.Threading.Tasks tasksCopy[i] = tasks[i]; if (tasksCopy[i] == null) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); + throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks)); } return tasksCopy; @@ -3038,7 +3040,7 @@ namespace System.Threading.Tasks if (tasks == null) throw new ArgumentNullException(nameof(tasks)); if (tasks.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks)); + throw new ArgumentException(SR.Task_MultiTaskContinuation_EmptyTaskList, nameof(tasks)); Contract.EndContractBlock(); Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length]; @@ -3047,7 +3049,7 @@ namespace System.Threading.Tasks tasksCopy[i] = tasks[i]; if (tasksCopy[i] == null) - throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks)); + throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks)); } return tasksCopy; @@ -3066,7 +3068,7 @@ namespace System.Threading.Tasks const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning; if ((continuationOptions & illegalMask) == illegalMask) { - throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_ContinueWith_ESandLR")); + throw new ArgumentOutOfRangeException(nameof(continuationOptions), SR.Task_ContinueWith_ESandLR); } // Check that no nonsensical options are specified. @@ -3085,9 +3087,8 @@ namespace System.Threading.Tasks // Check that no "fire" options are specified. if ((continuationOptions & NotOnAny) != 0) - throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions")); + throw new ArgumentOutOfRangeException(nameof(continuationOptions), SR.Task_MultiTaskContinuation_FireOptions); Contract.EndContractBlock(); } } - } |