Delete dead code in Task<T>
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Threading / Tasks / future.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
6 //
7 //
8 //
9 // A task that produces a value.
10 //
11 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
12
13 using System;
14 using System.Collections.Generic;
15 using System.Runtime;
16 using System.Runtime.CompilerServices;
17 using System.Runtime.ExceptionServices;
18 using System.Security;
19 using System.Threading;
20 using System.Diagnostics;
21
22 // Disable the "reference to volatile field not treated as volatile" error.
23 #pragma warning disable 0420
24
25 namespace System.Threading.Tasks
26 {
27     /// <summary>
28     /// Represents an asynchronous operation that produces a result at some time in the future.
29     /// </summary>
30     /// <typeparam name="TResult">
31     /// The type of the result produced by this <see cref="Task{TResult}"/>.
32     /// </typeparam>
33     /// <remarks>
34     /// <para>
35     /// <see cref="Task{TResult}"/> instances may be created in a variety of ways. The most common approach is by
36     /// using the task's <see cref="Factory"/> property to retrieve a <see
37     /// cref="System.Threading.Tasks.TaskFactory{TResult}"/> instance that can be used to create tasks for several
38     /// purposes. For example, to create a <see cref="Task{TResult}"/> that runs a function, the factory's StartNew
39     /// method may be used:
40     /// <code>
41     /// // C# 
42     /// var t = Task&lt;int&gt;.Factory.StartNew(() => GenerateResult());
43     /// - or -
44     /// var t = Task.Factory.StartNew(() => GenerateResult());
45     /// 
46     /// ' Visual Basic 
47     /// Dim t = Task&lt;int&gt;.Factory.StartNew(Function() GenerateResult())
48     /// - or -
49     /// Dim t = Task.Factory.StartNew(Function() GenerateResult())
50     /// </code>
51     /// </para>
52     /// <para>
53     /// The <see cref="Task{TResult}"/> class also provides constructors that initialize the task but that do not
54     /// schedule it for execution. For performance reasons, the StartNew method should be the
55     /// preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation
56     /// and scheduling must be separated, the constructors may be used, and the task's 
57     /// <see cref="System.Threading.Tasks.Task.Start()">Start</see>
58     /// method may then be used to schedule the task for execution at a later time.
59     /// </para>
60     /// <para>
61     /// All members of <see cref="Task{TResult}"/>, except for 
62     /// <see cref="System.Threading.Tasks.Task.Dispose()">Dispose</see>, are thread-safe
63     /// and may be used from multiple threads concurrently.
64     /// </para>
65     /// </remarks>
66     [DebuggerTypeProxy(typeof(SystemThreadingTasks_FutureDebugView<>))]
67     [DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")]
68     public class Task<TResult> : Task
69     {
70         internal TResult m_result; // The value itself, if set.
71
72         private static readonly TaskFactory<TResult> s_Factory = new TaskFactory<TResult>();
73
74         // Delegate used by:
75         //     public static Task<Task<TResult>> WhenAny<TResult>(IEnumerable<Task<TResult>> tasks);
76         //     public static Task<Task<TResult>> WhenAny<TResult>(params Task<TResult>[] tasks);
77         // Used to "cast" from Task<Task> to Task<Task<TResult>>.
78         internal static readonly Func<Task<Task>, Task<TResult>> TaskWhenAnyCast = completed => (Task<TResult>)completed.Result;
79
80         // Construct a promise-style task without any options. 
81         internal Task() :
82             base()
83         {
84         }
85
86         // Construct a promise-style task with state and options.  
87         internal Task(object state, TaskCreationOptions options) :
88             base(state, options, promiseStyle: true)
89         {
90         }
91
92
93         // Construct a pre-completed Task<TResult>
94         internal Task(TResult result) :
95             base(false, TaskCreationOptions.None, default)
96         {
97             m_result = result;
98         }
99
100         internal Task(bool canceled, TResult result, TaskCreationOptions creationOptions, CancellationToken ct)
101             : base(canceled, creationOptions, ct)
102         {
103             if (!canceled)
104             {
105                 m_result = result;
106             }
107         }
108
109         // Uncomment if/when we want Task.FromException
110         //// Construct a pre-faulted Task<TResult>
111         //internal Task(Exception exception)
112         //    : base(exception)
113         //{
114         //}
115
116         /// <summary>
117         /// Initializes a new <see cref="Task{TResult}"/> with the specified function.
118         /// </summary>
119         /// <param name="function">
120         /// The delegate that represents the code to execute in the task. When the function has completed,
121         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
122         /// </param>
123         /// <exception cref="T:System.ArgumentException">
124         /// The <paramref name="function"/> argument is null.
125         /// </exception>
126         public Task(Func<TResult> function)
127             : this(function, null, default,
128                 TaskCreationOptions.None, InternalTaskOptions.None, null)
129         {
130         }
131
132
133         /// <summary>
134         /// Initializes a new <see cref="Task{TResult}"/> with the specified function.
135         /// </summary>
136         /// <param name="function">
137         /// The delegate that represents the code to execute in the task. When the function has completed,
138         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
139         /// </param>
140         /// <param name="cancellationToken">The <see cref="CancellationToken"/> to be assigned to this task.</param>
141         /// <exception cref="T:System.ArgumentException">
142         /// The <paramref name="function"/> argument is null.
143         /// </exception>
144         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
145         /// has already been disposed.
146         /// </exception>
147         public Task(Func<TResult> function, CancellationToken cancellationToken)
148             : this(function, null, cancellationToken,
149                 TaskCreationOptions.None, InternalTaskOptions.None, null)
150         {
151         }
152
153         /// <summary>
154         /// Initializes a new <see cref="Task{TResult}"/> with the specified function and creation options.
155         /// </summary>
156         /// <param name="function">
157         /// The delegate that represents the code to execute in the task. When the function has completed,
158         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
159         /// </param>
160         /// <param name="creationOptions">
161         /// The <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions</see> used to
162         /// customize the task's behavior.
163         /// </param>
164         /// <exception cref="T:System.ArgumentException">
165         /// The <paramref name="function"/> argument is null.
166         /// </exception>
167         /// <exception cref="T:System.ArgumentOutOfRangeException">
168         /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
169         /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
170         /// </exception>
171         public Task(Func<TResult> function, TaskCreationOptions creationOptions)
172             : this(function, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, InternalTaskOptions.None, null)
173         {
174         }
175
176         /// <summary>
177         /// Initializes a new <see cref="Task{TResult}"/> with the specified function and creation options.
178         /// </summary>
179         /// <param name="function">
180         /// The delegate that represents the code to execute in the task. When the function has completed,
181         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
182         /// </param>
183         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
184         /// <param name="creationOptions">
185         /// The <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions</see> used to
186         /// customize the task's behavior.
187         /// </param>
188         /// <exception cref="T:System.ArgumentException">
189         /// The <paramref name="function"/> argument is null.
190         /// </exception>
191         /// <exception cref="T:System.ArgumentOutOfRangeException">
192         /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
193         /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
194         /// </exception>
195         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
196         /// has already been disposed.
197         /// </exception>
198         public Task(Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
199             : this(function, Task.InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, null)
200         {
201         }
202
203         /// <summary>
204         /// Initializes a new <see cref="Task{TResult}"/> with the specified function and state.
205         /// </summary>
206         /// <param name="function">
207         /// The delegate that represents the code to execute in the task. When the function has completed,
208         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
209         /// </param>
210         /// <param name="state">An object representing data to be used by the action.</param>
211         /// <exception cref="T:System.ArgumentException">
212         /// The <paramref name="function"/> argument is null.
213         /// </exception>
214         public Task(Func<object, TResult> function, object state)
215             : this(function, state, null, default,
216                 TaskCreationOptions.None, InternalTaskOptions.None, null)
217         {
218         }
219
220         /// <summary>
221         /// Initializes a new <see cref="Task{TResult}"/> with the specified action, state, and options.
222         /// </summary>
223         /// <param name="function">
224         /// The delegate that represents the code to execute in the task. When the function has completed,
225         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
226         /// </param>
227         /// <param name="state">An object representing data to be used by the function.</param>
228         /// <param name="cancellationToken">The <see cref="CancellationToken"/> to be assigned to the new task.</param>
229         /// <exception cref="T:System.ArgumentException">
230         /// The <paramref name="function"/> argument is null.
231         /// </exception>
232         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
233         /// has already been disposed.
234         /// </exception>
235         public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken)
236             : this(function, state, null, cancellationToken,
237                     TaskCreationOptions.None, InternalTaskOptions.None, null)
238         {
239         }
240
241         /// <summary>
242         /// Initializes a new <see cref="Task{TResult}"/> with the specified action, state, and options.
243         /// </summary>
244         /// <param name="function">
245         /// The delegate that represents the code to execute in the task. When the function has completed,
246         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
247         /// </param>
248         /// <param name="state">An object representing data to be used by the function.</param>
249         /// <param name="creationOptions">
250         /// The <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions</see> used to
251         /// customize the task's behavior.
252         /// </param>
253         /// <exception cref="T:System.ArgumentException">
254         /// The <paramref name="function"/> argument is null.
255         /// </exception>
256         /// <exception cref="T:System.ArgumentOutOfRangeException">
257         /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
258         /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
259         /// </exception>
260         public Task(Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
261             : this(function, state, Task.InternalCurrentIfAttached(creationOptions), default,
262                     creationOptions, InternalTaskOptions.None, null)
263         {
264         }
265
266
267         /// <summary>
268         /// Initializes a new <see cref="Task{TResult}"/> with the specified action, state, and options.
269         /// </summary>
270         /// <param name="function">
271         /// The delegate that represents the code to execute in the task. When the function has completed,
272         /// the task's <see cref="Result"/> property will be set to return the result value of the function.
273         /// </param>
274         /// <param name="state">An object representing data to be used by the function.</param>
275         /// <param name="cancellationToken">The <see cref="CancellationToken"/> to be assigned to the new task.</param>
276         /// <param name="creationOptions">
277         /// The <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions</see> used to
278         /// customize the task's behavior.
279         /// </param>
280         /// <exception cref="T:System.ArgumentException">
281         /// The <paramref name="function"/> argument is null.
282         /// </exception>
283         /// <exception cref="T:System.ArgumentOutOfRangeException">
284         /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see
285         /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>.
286         /// </exception>
287         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
288         /// has already been disposed.
289         /// </exception>
290         public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
291             : this(function, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken,
292                     creationOptions, InternalTaskOptions.None, null)
293         {
294         }
295
296         /// <summary>
297         /// Creates a new future object.
298         /// </summary>
299         /// <param name="parent">The parent task for this future.</param>
300         /// <param name="valueSelector">A function that yields the future value.</param>
301         /// <param name="scheduler">The task scheduler which will be used to execute the future.</param>
302         /// <param name="cancellationToken">The CancellationToken for the task.</param>
303         /// <param name="creationOptions">Options to control the future's behavior.</param>
304         /// <param name="internalOptions">Internal options to control the future's behavior.</param>
305         internal Task(Func<TResult> valueSelector, Task parent, CancellationToken cancellationToken,
306             TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) :
307             base(valueSelector, null, parent, cancellationToken, creationOptions, internalOptions, scheduler)
308         {
309         }
310
311         /// <summary>
312         /// Creates a new future object.
313         /// </summary>
314         /// <param name="parent">The parent task for this future.</param>
315         /// <param name="state">An object containing data to be used by the action; may be null.</param>
316         /// <param name="valueSelector">A function that yields the future value.</param>
317         /// <param name="cancellationToken">The CancellationToken for the task.</param>
318         /// <param name="scheduler">The task scheduler which will be used to execute the future.</param>
319         /// <param name="creationOptions">Options to control the future's behavior.</param>
320         /// <param name="internalOptions">Internal options to control the future's behavior.</param>
321         internal Task(Delegate valueSelector, object state, Task parent, CancellationToken cancellationToken,
322             TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) :
323             base(valueSelector, state, parent, cancellationToken, creationOptions, internalOptions, scheduler)
324         {
325         }
326
327
328         // Internal method used by TaskFactory<TResult>.StartNew() methods
329         internal static Task<TResult> StartNew(Task parent, Func<TResult> function, CancellationToken cancellationToken,
330             TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
331         {
332             if (function == null)
333             {
334                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.function);
335             }
336             if (scheduler == null)
337             {
338                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
339             }
340
341             // Create and schedule the future.
342             Task<TResult> f = new Task<TResult>(function, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler);
343
344             f.ScheduleAndStart(false);
345             return f;
346         }
347
348         // Internal method used by TaskFactory<TResult>.StartNew() methods
349         internal static Task<TResult> StartNew(Task parent, Func<object, TResult> function, object state, CancellationToken cancellationToken,
350             TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
351         {
352             if (function == null)
353             {
354                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.function);
355             }
356             if (scheduler == null)
357             {
358                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
359             }
360
361             // Create and schedule the future.
362             Task<TResult> f = new Task<TResult>(function, state, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler);
363
364             f.ScheduleAndStart(false);
365             return f;
366         }
367
368         // Debugger support
369         private string DebuggerDisplayResultDescription
370         {
371             get
372             {
373                 return IsCompletedSuccessfully ? "" + m_result : SR.TaskT_DebuggerNoResult;
374             }
375         }
376
377         // Debugger support
378         private string DebuggerDisplayMethodDescription
379         {
380             get
381             {
382                 Delegate d = m_action;
383                 return d != null ? d.Method.ToString() : "{null}";
384             }
385         }
386
387
388         // internal helper function breaks out logic used by TaskCompletionSource
389         internal bool TrySetResult(TResult result)
390         {
391             Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
392
393             // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
394             // has been made, (2) The result has not already been set, (3) An exception has not previously 
395             // been recorded, and (4) Cancellation has not been requested.
396             //
397             // If the reservation is successful, then set the result and finish completion processing.
398             if (AtomicStateUpdate(TASK_STATE_COMPLETION_RESERVED,
399                     TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
400             {
401                 m_result = result;
402
403                 // Signal completion, for waiting tasks
404
405                 // This logic used to be:
406                 //     Finish(false);
407                 // However, that goes through a windy code path, involves many non-inlineable functions
408                 // and which can be summarized more concisely with the following snippet from
409                 // FinishStageTwo, omitting everything that doesn't pertain to TrySetResult.
410                 Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_RAN_TO_COMPLETION);
411                 ContingentProperties props = m_contingentProperties;
412                 if (props != null)
413                 {
414                     NotifyParentIfPotentiallyAttachedTask();
415                     props.SetCompleted();
416                 }
417                 FinishContinuations();
418                 return true;
419             }
420
421             return false;
422         }
423
424         // Transitions the promise task into a successfully completed state with the specified result.
425         // This is dangerous, as no synchronization is used, and thus must only be used
426         // before this task is handed out to any consumers, before any continuations are hooked up,
427         // before its wait handle is accessed, etc.  It's use is limited to places like in FromAsync
428         // where the operation completes synchronously, and thus we know we can forcefully complete
429         // the task, avoiding expensive completion paths, before the task is actually given to anyone.
430         internal void DangerousSetResult(TResult result)
431         {
432             Debug.Assert(!IsCompleted, "The promise must not yet be completed.");
433
434             // If we have a parent, we need to notify it of the completion.  Take the slow path to handle that.
435             if (m_contingentProperties?.m_parent != null)
436             {
437                 bool success = TrySetResult(result);
438
439                 // Nobody else has had a chance to complete this Task yet, so we should succeed.
440                 Debug.Assert(success);
441             }
442             else
443             {
444                 m_result = result;
445                 m_stateFlags |= TASK_STATE_RAN_TO_COMPLETION;
446             }
447         }
448
449         /// <summary>
450         /// Gets the result value of this <see cref="Task{TResult}"/>.
451         /// </summary>
452         /// <remarks>
453         /// The get accessor for this property ensures that the asynchronous operation is complete before
454         /// returning. Once the result of the computation is available, it is stored and will be returned
455         /// immediately on later calls to <see cref="Result"/>.
456         /// </remarks>
457         [DebuggerBrowsable(DebuggerBrowsableState.Never)]
458         public TResult Result
459         {
460             get { return IsWaitNotificationEnabledOrNotRanToCompletion ? GetResultCore(waitCompletionNotification: true) : m_result; }
461         }
462
463         /// <summary>
464         /// Gets the result value of this <see cref="Task{TResult}"/> once the task has completed successfully.
465         /// </summary>
466         /// <remarks>
467         /// This version of Result should only be used if the task completed successfully and if there's
468         /// no debugger wait notification enabled for this task.
469         /// </remarks>
470         internal TResult ResultOnSuccess
471         {
472             get
473             {
474                 Debug.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
475                     "Should only be used when the task completed successfully and there's no wait notification enabled");
476                 return m_result;
477             }
478         }
479
480         // Implements Result.  Result delegates to this method if the result isn't already available.
481         internal TResult GetResultCore(bool waitCompletionNotification)
482         {
483             // If the result has not been calculated yet, wait for it.
484             if (!IsCompleted) InternalWait(Timeout.Infinite, default); // won't throw if task faulted or canceled; that's handled below
485
486             // Notify the debugger of the wait completion if it's requested such a notification
487             if (waitCompletionNotification) NotifyDebuggerOfWaitCompletionIfNecessary();
488
489             // Throw an exception if appropriate.
490             if (!IsCompletedSuccessfully) ThrowIfExceptional(includeTaskCanceledExceptions: true);
491
492             // We shouldn't be here if the result has not been set.
493             Debug.Assert(IsCompletedSuccessfully, "Task<T>.Result getter: Expected result to have been set.");
494
495             return m_result;
496         }
497
498         // Allow multiple exceptions to be assigned to a promise-style task.
499         // This is useful when a TaskCompletionSource<T> stands in as a proxy
500         // for a "real" task (as we do in Unwrap(), ContinueWhenAny() and ContinueWhenAll())
501         // and the "real" task ends up with multiple exceptions, which is possible when
502         // a task has children.
503         //
504         // Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>).
505         internal bool TrySetException(object exceptionObject)
506         {
507             Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");
508
509             // TCS.{Try}SetException() should have checked for this
510             Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");
511
512             // Only accept these types.
513             Debug.Assert(
514                 (exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) ||
515                 (exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>),
516                 "Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those");
517
518             bool returnValue = false;
519
520             // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
521             // has been made, (2) The result has not already been set, (3) An exception has not previously 
522             // been recorded, and (4) Cancellation has not been requested.
523             //
524             // If the reservation is successful, then add the exception(s) and finish completion processing.
525             //
526             // The lazy initialization may not be strictly necessary, but I'd like to keep it here
527             // anyway.  Some downstream logic may depend upon an inflated m_contingentProperties.
528             EnsureContingentPropertiesInitialized();
529             if (AtomicStateUpdate(TASK_STATE_COMPLETION_RESERVED,
530                 TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
531             {
532                 AddException(exceptionObject); // handles singleton exception or exception collection
533                 Finish(false);
534                 returnValue = true;
535             }
536
537             return returnValue;
538         }
539
540         // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
541         // If the tokenToRecord is not None, it will be stored onto the task.
542         // This method is only valid for promise tasks.
543         internal bool TrySetCanceled(CancellationToken tokenToRecord)
544         {
545             return TrySetCanceled(tokenToRecord, null);
546         }
547
548         // internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
549         // If the tokenToRecord is not None, it will be stored onto the task.
550         // If the OperationCanceledException is not null, it will be stored into the task's exception holder.
551         // This method is only valid for promise tasks.
552         internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException)
553         {
554             Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
555 #if DEBUG
556             var ceAsEdi = cancellationException as ExceptionDispatchInfo;
557             Debug.Assert(
558                 cancellationException == null ||
559                 cancellationException is OperationCanceledException ||
560                 (ceAsEdi != null && ceAsEdi.SourceException is OperationCanceledException),
561                 "Expected null or an OperationCanceledException");
562 #endif
563
564             bool returnValue = false;
565
566             // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
567             // has been made, (2) The result has not already been set, (3) An exception has not previously 
568             // been recorded, and (4) Cancellation has not been requested.
569             //
570             // If the reservation is successful, then record the cancellation and finish completion processing.
571             //
572             // Note: I had to access static Task variables through Task<object>
573             // instead of Task, because I have a property named Task and that
574             // was confusing the compiler.  
575             if (AtomicStateUpdate(Task<object>.TASK_STATE_COMPLETION_RESERVED,
576                 Task<object>.TASK_STATE_COMPLETION_RESERVED | Task<object>.TASK_STATE_CANCELED |
577                 Task<object>.TASK_STATE_FAULTED | Task<object>.TASK_STATE_RAN_TO_COMPLETION))
578             {
579                 RecordInternalCancellationRequest(tokenToRecord, cancellationException);
580                 CancellationCleanupLogic(); // perform cancellation cleanup actions
581                 returnValue = true;
582             }
583
584             return returnValue;
585         }
586
587         /// <summary>
588         /// Provides access to factory methods for creating <see cref="Task{TResult}"/> instances.
589         /// </summary>
590         /// <remarks>
591         /// The factory returned from <see cref="Factory"/> is a default instance
592         /// of <see cref="System.Threading.Tasks.TaskFactory{TResult}"/>, as would result from using
593         /// the default constructor on the factory type.
594         /// </remarks>
595         public new static TaskFactory<TResult> Factory { get { return s_Factory; } }
596
597         /// <summary>
598         /// Evaluates the value selector of the Task which is passed in as an object and stores the result.
599         /// </summary>        
600         internal override void InnerInvoke()
601         {
602             // Invoke the delegate
603             Debug.Assert(m_action != null);
604             var func = m_action as Func<TResult>;
605             if (func != null)
606             {
607                 m_result = func();
608                 return;
609             }
610             var funcWithState = m_action as Func<object, TResult>;
611             if (funcWithState != null)
612             {
613                 m_result = funcWithState(m_stateObject);
614                 return;
615             }
616             Debug.Fail("Invalid m_action in Task<TResult>");
617         }
618
619         #region Await Support
620
621         /// <summary>Gets an awaiter used to await this <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
622         /// <returns>An awaiter instance.</returns>
623         /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
624         public new TaskAwaiter<TResult> GetAwaiter()
625         {
626             return new TaskAwaiter<TResult>(this);
627         }
628
629         /// <summary>Configures an awaiter used to await this <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
630         /// <param name="continueOnCapturedContext">
631         /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
632         /// </param>
633         /// <returns>An object used to await this task.</returns>
634         public new ConfiguredTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext)
635         {
636             return new ConfiguredTaskAwaitable<TResult>(this, continueOnCapturedContext);
637         }
638
639         #endregion
640
641         #region Continuation methods
642
643         #region Action<Task<TResult>> continuations
644
645         /// <summary>
646         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
647         /// </summary>
648         /// <param name="continuationAction">
649         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
650         /// passed the completed task as an argument.
651         /// </param>
652         /// <returns>A new continuation <see cref="Task"/>.</returns>
653         /// <remarks>
654         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
655         /// completed, whether it completes due to running to completion successfully, faulting due to an
656         /// unhandled exception, or exiting out early due to being canceled.
657         /// </remarks>
658         /// <exception cref="T:System.ArgumentNullException">
659         /// The <paramref name="continuationAction"/> argument is null.
660         /// </exception>
661         public Task ContinueWith(Action<Task<TResult>> continuationAction)
662         {
663             return ContinueWith(continuationAction, TaskScheduler.Current, default, TaskContinuationOptions.None);
664         }
665
666
667         /// <summary>
668         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
669         /// </summary>
670         /// <param name="continuationAction">
671         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
672         /// passed the completed task as an argument.
673         /// </param>
674         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new continuation task.</param>
675         /// <returns>A new continuation <see cref="Task"/>.</returns>
676         /// <remarks>
677         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
678         /// completed, whether it completes due to running to completion successfully, faulting due to an
679         /// unhandled exception, or exiting out early due to being canceled.
680         /// </remarks>
681         /// <exception cref="T:System.ArgumentNullException">
682         /// The <paramref name="continuationAction"/> argument is null.
683         /// </exception>
684         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
685         /// has already been disposed.
686         /// </exception>
687         public Task ContinueWith(Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
688         {
689             return ContinueWith(continuationAction, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
690         }
691
692
693         /// <summary>
694         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
695         /// </summary>
696         /// <param name="continuationAction">
697         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
698         /// passed the completed task as an argument.
699         /// </param>
700         /// <param name="scheduler">
701         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its execution.
702         /// </param>
703         /// <returns>A new continuation <see cref="Task"/>.</returns>
704         /// <remarks>
705         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
706         /// completed, whether it completes due to running to completion successfully, faulting due to an
707         /// unhandled exception, or exiting out early due to being canceled.
708         /// </remarks>
709         /// <exception cref="T:System.ArgumentNullException">
710         /// The <paramref name="continuationAction"/> argument is null.
711         /// </exception>
712         /// <exception cref="T:System.ArgumentNullException">
713         /// The <paramref name="scheduler"/> argument is null.
714         /// </exception>
715         public Task ContinueWith(Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
716         {
717             return ContinueWith(continuationAction, scheduler, default, TaskContinuationOptions.None);
718         }
719
720         /// <summary>
721         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
722         /// </summary>
723         /// <param name="continuationAction">
724         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
725         /// passed the completed task as an argument.
726         /// </param>
727         /// <param name="continuationOptions">
728         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
729         /// as <see
730         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
731         /// well as execution options, such as <see
732         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
733         /// </param>
734         /// <returns>A new continuation <see cref="Task"/>.</returns>
735         /// <remarks>
736         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
737         /// completed. If the continuation criteria specified through the <paramref
738         /// name="continuationOptions"/> parameter are not met, the continuation task will be canceled
739         /// instead of scheduled.
740         /// </remarks>
741         /// <exception cref="T:System.ArgumentNullException">
742         /// The <paramref name="continuationAction"/> argument is null.
743         /// </exception>
744         /// <exception cref="T:System.ArgumentOutOfRangeException">
745         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
746         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
747         /// </exception>
748         public Task ContinueWith(Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
749         {
750             return ContinueWith(continuationAction, TaskScheduler.Current, default, continuationOptions);
751         }
752
753         /// <summary>
754         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
755         /// </summary>
756         /// <param name="continuationAction">
757         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
758         /// passed the completed task as an argument.
759         /// </param>
760         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new continuation task.</param>
761         /// <param name="continuationOptions">
762         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
763         /// as <see
764         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
765         /// well as execution options, such as <see
766         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
767         /// </param>
768         /// <param name="scheduler">
769         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its
770         /// execution.
771         /// </param>
772         /// <returns>A new continuation <see cref="Task"/>.</returns>
773         /// <remarks>
774         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
775         /// completed. If the criteria specified through the <paramref name="continuationOptions"/> parameter
776         /// are not met, the continuation task will be canceled instead of scheduled.
777         /// </remarks>
778         /// <exception cref="T:System.ArgumentNullException">
779         /// The <paramref name="continuationAction"/> argument is null.
780         /// </exception>
781         /// <exception cref="T:System.ArgumentOutOfRangeException">
782         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
783         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
784         /// </exception>
785         /// <exception cref="T:System.ArgumentNullException">
786         /// The <paramref name="scheduler"/> argument is null.
787         /// </exception>
788         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
789         /// has already been disposed.
790         /// </exception>
791         public Task ContinueWith(Action<Task<TResult>> continuationAction, CancellationToken cancellationToken,
792                                  TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
793         {
794             return ContinueWith(continuationAction, scheduler, cancellationToken, continuationOptions);
795         }
796
797         // Same as the above overload, only with a stack mark.
798         internal Task ContinueWith(Action<Task<TResult>> continuationAction, TaskScheduler scheduler, CancellationToken cancellationToken,
799                                    TaskContinuationOptions continuationOptions)
800         {
801             if (continuationAction == null)
802             {
803                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.continuationAction);
804             }
805
806             if (scheduler == null)
807             {
808                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
809             }
810
811             TaskCreationOptions creationOptions;
812             InternalTaskOptions internalOptions;
813             CreationOptionsFromContinuationOptions(
814                 continuationOptions,
815                 out creationOptions,
816                 out internalOptions);
817
818             Task continuationTask = new ContinuationTaskFromResultTask<TResult>(
819                 this, continuationAction, null,
820                 creationOptions, internalOptions
821             );
822
823             // Register the continuation.  If synchronous execution is requested, this may
824             // actually invoke the continuation before returning.
825             ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions);
826
827             return continuationTask;
828         }
829         #endregion
830
831         #region Action<Task<TResult>, Object> continuations
832
833         /// <summary>
834         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
835         /// </summary>
836         /// <param name="continuationAction">
837         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
838         /// passed the completed task and the caller-supplied state object as arguments.
839         /// </param>
840         /// <param name="state">An object representing data to be used by the continuation action.</param>
841         /// <returns>A new continuation <see cref="Task"/>.</returns>
842         /// <remarks>
843         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
844         /// completed, whether it completes due to running to completion successfully, faulting due to an
845         /// unhandled exception, or exiting out early due to being canceled.
846         /// </remarks>
847         /// <exception cref="T:System.ArgumentNullException">
848         /// The <paramref name="continuationAction"/> argument is null.
849         /// </exception>
850         public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state)
851         {
852             return ContinueWith(continuationAction, state, TaskScheduler.Current, default, TaskContinuationOptions.None);
853         }
854
855
856         /// <summary>
857         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
858         /// </summary>
859         /// <param name="continuationAction">
860         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
861         /// passed the completed task and the caller-supplied state object as arguments.
862         /// </param>
863         /// <param name="state">An object representing data to be used by the continuation action.</param>
864         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new continuation task.</param>
865         /// <returns>A new continuation <see cref="Task"/>.</returns>
866         /// <remarks>
867         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
868         /// completed, whether it completes due to running to completion successfully, faulting due to an
869         /// unhandled exception, or exiting out early due to being canceled.
870         /// </remarks>
871         /// <exception cref="T:System.ArgumentNullException">
872         /// The <paramref name="continuationAction"/> argument is null.
873         /// </exception>
874         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
875         /// has already been disposed.
876         /// </exception>
877         public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
878         {
879             return ContinueWith(continuationAction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
880         }
881
882
883         /// <summary>
884         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
885         /// </summary>
886         /// <param name="continuationAction">
887         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
888         /// passed the completed task and the caller-supplied state object as arguments.
889         /// </param>
890         /// <param name="state">An object representing data to be used by the continuation action.</param>
891         /// <param name="scheduler">
892         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its execution.
893         /// </param>
894         /// <returns>A new continuation <see cref="Task"/>.</returns>
895         /// <remarks>
896         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
897         /// completed, whether it completes due to running to completion successfully, faulting due to an
898         /// unhandled exception, or exiting out early due to being canceled.
899         /// </remarks>
900         /// <exception cref="T:System.ArgumentNullException">
901         /// The <paramref name="continuationAction"/> argument is null.
902         /// </exception>
903         /// <exception cref="T:System.ArgumentNullException">
904         /// The <paramref name="scheduler"/> argument is null.
905         /// </exception>
906         public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
907         {
908             return ContinueWith(continuationAction, state, scheduler, default, TaskContinuationOptions.None);
909         }
910
911         /// <summary>
912         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
913         /// </summary>
914         /// <param name="continuationAction">
915         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
916         /// passed the completed task and the caller-supplied state object as arguments.
917         /// </param>
918         /// <param name="state">An object representing data to be used by the continuation action.</param>
919         /// <param name="continuationOptions">
920         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
921         /// as <see
922         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
923         /// well as execution options, such as <see
924         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
925         /// </param>
926         /// <returns>A new continuation <see cref="Task"/>.</returns>
927         /// <remarks>
928         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
929         /// completed. If the continuation criteria specified through the <paramref
930         /// name="continuationOptions"/> parameter are not met, the continuation task will be canceled
931         /// instead of scheduled.
932         /// </remarks>
933         /// <exception cref="T:System.ArgumentNullException">
934         /// The <paramref name="continuationAction"/> argument is null.
935         /// </exception>
936         /// <exception cref="T:System.ArgumentOutOfRangeException">
937         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
938         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
939         /// </exception>
940         public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
941         {
942             return ContinueWith(continuationAction, state, TaskScheduler.Current, default, continuationOptions);
943         }
944
945         /// <summary>
946         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
947         /// </summary>
948         /// <param name="continuationAction">
949         /// An action to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
950         /// passed the completed task and the caller-supplied state object as arguments.
951         /// </param>
952         /// <param name="state">An object representing data to be used by the continuation action.</param>
953         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new continuation task.</param>
954         /// <param name="continuationOptions">
955         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
956         /// as <see
957         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
958         /// well as execution options, such as <see
959         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
960         /// </param>
961         /// <param name="scheduler">
962         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its
963         /// execution.
964         /// </param>
965         /// <returns>A new continuation <see cref="Task"/>.</returns>
966         /// <remarks>
967         /// The returned <see cref="Task"/> will not be scheduled for execution until the current task has
968         /// completed. If the criteria specified through the <paramref name="continuationOptions"/> parameter
969         /// are not met, the continuation task will be canceled instead of scheduled.
970         /// </remarks>
971         /// <exception cref="T:System.ArgumentNullException">
972         /// The <paramref name="continuationAction"/> argument is null.
973         /// </exception>
974         /// <exception cref="T:System.ArgumentOutOfRangeException">
975         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
976         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
977         /// </exception>
978         /// <exception cref="T:System.ArgumentNullException">
979         /// The <paramref name="scheduler"/> argument is null.
980         /// </exception>
981         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
982         /// has already been disposed.
983         /// </exception>
984         public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken,
985                                  TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
986         {
987             return ContinueWith(continuationAction, state, scheduler, cancellationToken, continuationOptions);
988         }
989
990         // Same as the above overload, only with a stack mark.
991         internal Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler, CancellationToken cancellationToken,
992                                    TaskContinuationOptions continuationOptions)
993         {
994             if (continuationAction == null)
995             {
996                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.continuationAction);
997             }
998
999             if (scheduler == null)
1000             {
1001                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
1002             }
1003
1004             TaskCreationOptions creationOptions;
1005             InternalTaskOptions internalOptions;
1006             CreationOptionsFromContinuationOptions(
1007                 continuationOptions,
1008                 out creationOptions,
1009                 out internalOptions);
1010
1011             Task continuationTask = new ContinuationTaskFromResultTask<TResult>(
1012                 this, continuationAction, state,
1013                 creationOptions, internalOptions
1014             );
1015
1016             // Register the continuation.  If synchronous execution is requested, this may
1017             // actually invoke the continuation before returning.
1018             ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions);
1019
1020             return continuationTask;
1021         }
1022
1023         #endregion
1024
1025         #region Func<Task<TResult>,TNewResult> continuations
1026
1027         /// <summary>
1028         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1029         /// </summary>
1030         /// <typeparam name="TNewResult">
1031         /// The type of the result produced by the continuation.
1032         /// </typeparam>
1033         /// <param name="continuationFunction">
1034         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1035         /// passed the completed task as an argument.
1036         /// </param>
1037         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1038         /// <remarks>
1039         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1040         /// task has completed, whether it completes due to running to completion successfully, faulting due
1041         /// to an unhandled exception, or exiting out early due to being canceled.
1042         /// </remarks>
1043         /// <exception cref="T:System.ArgumentNullException">
1044         /// The <paramref name="continuationFunction"/> argument is null.
1045         /// </exception>
1046         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction)
1047         {
1048             return ContinueWith<TNewResult>(continuationFunction, TaskScheduler.Current, default, TaskContinuationOptions.None);
1049         }
1050
1051
1052         /// <summary>
1053         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1054         /// </summary>
1055         /// <typeparam name="TNewResult">
1056         /// The type of the result produced by the continuation.
1057         /// </typeparam>
1058         /// <param name="continuationFunction">
1059         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1060         /// passed the completed task as an argument.
1061         /// </param>
1062         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
1063         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1064         /// <remarks>
1065         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1066         /// task has completed, whether it completes due to running to completion successfully, faulting due
1067         /// to an unhandled exception, or exiting out early due to being canceled.
1068         /// </remarks>
1069         /// <exception cref="T:System.ArgumentNullException">
1070         /// The <paramref name="continuationFunction"/> argument is null.
1071         /// </exception>
1072         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1073         /// has already been disposed.
1074         /// </exception>
1075         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
1076         {
1077             return ContinueWith<TNewResult>(continuationFunction, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
1078         }
1079
1080         /// <summary>
1081         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1082         /// </summary>
1083         /// <typeparam name="TNewResult">
1084         /// The type of the result produced by the continuation.
1085         /// </typeparam>
1086         /// <param name="continuationFunction">
1087         /// A function to run when the <see cref="Task{TResult}"/> completes.  When run, the delegate will be
1088         /// passed the completed task as an argument.
1089         /// </param>
1090         /// <param name="scheduler">
1091         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its execution.
1092         /// </param>
1093         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1094         /// <remarks>
1095         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current task has
1096         /// completed, whether it completes due to running to completion successfully, faulting due to an
1097         /// unhandled exception, or exiting out early due to being canceled.
1098         /// </remarks>
1099         /// <exception cref="T:System.ArgumentNullException">
1100         /// The <paramref name="continuationFunction"/> argument is null.
1101         /// </exception>
1102         /// <exception cref="T:System.ArgumentNullException">
1103         /// The <paramref name="scheduler"/> argument is null.
1104         /// </exception>
1105         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
1106         {
1107             return ContinueWith<TNewResult>(continuationFunction, scheduler, default, TaskContinuationOptions.None);
1108         }
1109
1110         /// <summary>
1111         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1112         /// </summary>
1113         /// <typeparam name="TNewResult">
1114         /// The type of the result produced by the continuation.
1115         /// </typeparam>
1116         /// <param name="continuationFunction">
1117         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1118         /// passed the completed task as an argument.
1119         /// </param>
1120         /// <param name="continuationOptions">
1121         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
1122         /// as <see
1123         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
1124         /// well as execution options, such as <see
1125         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
1126         /// </param>
1127         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1128         /// <remarks>
1129         /// <para>
1130         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1131         /// task has completed, whether it completes due to running to completion successfully, faulting due
1132         /// to an unhandled exception, or exiting out early due to being canceled.
1133         /// </para>
1134         /// <para>
1135         /// The <paramref name="continuationFunction"/>, when executed, should return a <see
1136         /// cref="Task{TNewResult}"/>. This task's completion state will be transferred to the task returned
1137         /// from the ContinueWith call.
1138         /// </para>
1139         /// </remarks>
1140         /// <exception cref="T:System.ArgumentNullException">
1141         /// The <paramref name="continuationFunction"/> argument is null.
1142         /// </exception>
1143         /// <exception cref="T:System.ArgumentOutOfRangeException">
1144         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
1145         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
1146         /// </exception>
1147         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
1148         {
1149             return ContinueWith<TNewResult>(continuationFunction, TaskScheduler.Current, default, continuationOptions);
1150         }
1151
1152         /// <summary>
1153         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1154         /// </summary>
1155         /// <typeparam name="TNewResult">
1156         /// The type of the result produced by the continuation.
1157         /// </typeparam>
1158         /// <param name="continuationFunction">
1159         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be passed as
1160         /// an argument this completed task.
1161         /// </param>
1162         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
1163         /// <param name="continuationOptions">
1164         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
1165         /// as <see
1166         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
1167         /// well as execution options, such as <see
1168         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
1169         /// </param>
1170         /// <param name="scheduler">
1171         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its
1172         /// execution.
1173         /// </param>
1174         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1175         /// <remarks>
1176         /// <para>
1177         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current task has
1178         /// completed, whether it completes due to running to completion successfully, faulting due to an
1179         /// unhandled exception, or exiting out early due to being canceled.
1180         /// </para>
1181         /// <para>
1182         /// The <paramref name="continuationFunction"/>, when executed, should return a <see cref="Task{TNewResult}"/>.
1183         /// This task's completion state will be transferred to the task returned from the
1184         /// ContinueWith call.
1185         /// </para>
1186         /// </remarks>
1187         /// <exception cref="T:System.ArgumentNullException">
1188         /// The <paramref name="continuationFunction"/> argument is null.
1189         /// </exception>
1190         /// <exception cref="T:System.ArgumentOutOfRangeException">
1191         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
1192         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
1193         /// </exception>
1194         /// <exception cref="T:System.ArgumentNullException">
1195         /// The <paramref name="scheduler"/> argument is null.
1196         /// </exception>
1197         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1198         /// has already been disposed.
1199         /// </exception>
1200         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken,
1201             TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
1202         {
1203             return ContinueWith<TNewResult>(continuationFunction, scheduler, cancellationToken, continuationOptions);
1204         }
1205
1206         // Same as the above overload, just with a stack mark.
1207         internal Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler,
1208             CancellationToken cancellationToken, TaskContinuationOptions continuationOptions)
1209         {
1210             if (continuationFunction == null)
1211             {
1212                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.continuationFunction);
1213             }
1214
1215             if (scheduler == null)
1216             {
1217                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
1218             }
1219
1220             TaskCreationOptions creationOptions;
1221             InternalTaskOptions internalOptions;
1222             CreationOptionsFromContinuationOptions(
1223                 continuationOptions,
1224                 out creationOptions,
1225                 out internalOptions);
1226
1227             Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
1228                 this, continuationFunction, null,
1229                 creationOptions, internalOptions
1230             );
1231
1232             // Register the continuation.  If synchronous execution is requested, this may
1233             // actually invoke the continuation before returning.
1234             ContinueWithCore(continuationFuture, scheduler, cancellationToken, continuationOptions);
1235
1236             return continuationFuture;
1237         }
1238         #endregion
1239
1240         #region Func<Task<TResult>, Object,TNewResult> continuations
1241
1242         /// <summary>
1243         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1244         /// </summary>
1245         /// <typeparam name="TNewResult">
1246         /// The type of the result produced by the continuation.
1247         /// </typeparam>
1248         /// <param name="continuationFunction">
1249         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1250         /// passed the completed task and the caller-supplied state object as arguments.
1251         /// </param>
1252         /// <param name="state">An object representing data to be used by the continuation function.</param>
1253         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1254         /// <remarks>
1255         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1256         /// task has completed, whether it completes due to running to completion successfully, faulting due
1257         /// to an unhandled exception, or exiting out early due to being canceled.
1258         /// </remarks>
1259         /// <exception cref="T:System.ArgumentNullException">
1260         /// The <paramref name="continuationFunction"/> argument is null.
1261         /// </exception>
1262         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
1263         {
1264             return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, default, TaskContinuationOptions.None);
1265         }
1266
1267
1268         /// <summary>
1269         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1270         /// </summary>
1271         /// <typeparam name="TNewResult">
1272         /// The type of the result produced by the continuation.
1273         /// </typeparam>
1274         /// <param name="continuationFunction">
1275         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1276         /// passed the completed task and the caller-supplied state object as arguments.
1277         /// </param>
1278         /// <param name="state">An object representing data to be used by the continuation function.</param>
1279         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
1280         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1281         /// <remarks>
1282         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1283         /// task has completed, whether it completes due to running to completion successfully, faulting due
1284         /// to an unhandled exception, or exiting out early due to being canceled.
1285         /// </remarks>
1286         /// <exception cref="T:System.ArgumentNullException">
1287         /// The <paramref name="continuationFunction"/> argument is null.
1288         /// </exception>
1289         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1290         /// has already been disposed.
1291         /// </exception>
1292         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
1293             CancellationToken cancellationToken)
1294         {
1295             return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
1296         }
1297
1298         /// <summary>
1299         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1300         /// </summary>
1301         /// <typeparam name="TNewResult">
1302         /// The type of the result produced by the continuation.
1303         /// </typeparam>
1304         /// <param name="continuationFunction">
1305         /// A function to run when the <see cref="Task{TResult}"/> completes.  When run, the delegate will be
1306         /// passed the completed task and the caller-supplied state object as arguments.
1307         /// </param>
1308         /// <param name="state">An object representing data to be used by the continuation function.</param>
1309         /// <param name="scheduler">
1310         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its execution.
1311         /// </param>
1312         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1313         /// <remarks>
1314         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current task has
1315         /// completed, whether it completes due to running to completion successfully, faulting due to an
1316         /// unhandled exception, or exiting out early due to being canceled.
1317         /// </remarks>
1318         /// <exception cref="T:System.ArgumentNullException">
1319         /// The <paramref name="continuationFunction"/> argument is null.
1320         /// </exception>
1321         /// <exception cref="T:System.ArgumentNullException">
1322         /// The <paramref name="scheduler"/> argument is null.
1323         /// </exception>
1324         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
1325             TaskScheduler scheduler)
1326         {
1327             return ContinueWith<TNewResult>(continuationFunction, state, scheduler, default, TaskContinuationOptions.None);
1328         }
1329
1330         /// <summary>
1331         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1332         /// </summary>
1333         /// <typeparam name="TNewResult">
1334         /// The type of the result produced by the continuation.
1335         /// </typeparam>
1336         /// <param name="continuationFunction">
1337         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1338         /// passed the completed task and the caller-supplied state object as arguments.
1339         /// </param>
1340         /// <param name="state">An object representing data to be used by the continuation function.</param>
1341         /// <param name="continuationOptions">
1342         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
1343         /// as <see
1344         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
1345         /// well as execution options, such as <see
1346         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
1347         /// </param>
1348         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1349         /// <remarks>
1350         /// <para>
1351         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current
1352         /// task has completed, whether it completes due to running to completion successfully, faulting due
1353         /// to an unhandled exception, or exiting out early due to being canceled.
1354         /// </para>
1355         /// <para>
1356         /// The <paramref name="continuationFunction"/>, when executed, should return a <see
1357         /// cref="Task{TNewResult}"/>. This task's completion state will be transferred to the task returned
1358         /// from the ContinueWith call.
1359         /// </para>
1360         /// </remarks>
1361         /// <exception cref="T:System.ArgumentNullException">
1362         /// The <paramref name="continuationFunction"/> argument is null.
1363         /// </exception>
1364         /// <exception cref="T:System.ArgumentOutOfRangeException">
1365         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
1366         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
1367         /// </exception>
1368         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
1369             TaskContinuationOptions continuationOptions)
1370         {
1371             return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, default, continuationOptions);
1372         }
1373
1374         /// <summary>
1375         /// Creates a continuation that executes when the target <see cref="Task{TResult}"/> completes.
1376         /// </summary>
1377         /// <typeparam name="TNewResult">
1378         /// The type of the result produced by the continuation.
1379         /// </typeparam>
1380         /// <param name="continuationFunction">
1381         /// A function to run when the <see cref="Task{TResult}"/> completes. When run, the delegate will be
1382         /// passed the completed task and the caller-supplied state object as arguments.
1383         /// </param>
1384         /// <param name="state">An object representing data to be used by the continuation function.</param>
1385         /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
1386         /// <param name="continuationOptions">
1387         /// Options for when the continuation is scheduled and how it behaves. This includes criteria, such
1388         /// as <see
1389         /// cref="System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled">OnlyOnCanceled</see>, as
1390         /// well as execution options, such as <see
1391         /// cref="System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously">ExecuteSynchronously</see>.
1392         /// </param>
1393         /// <param name="scheduler">
1394         /// The <see cref="TaskScheduler"/> to associate with the continuation task and to use for its
1395         /// execution.
1396         /// </param>
1397         /// <returns>A new continuation <see cref="Task{TNewResult}"/>.</returns>
1398         /// <remarks>
1399         /// <para>
1400         /// The returned <see cref="Task{TNewResult}"/> will not be scheduled for execution until the current task has
1401         /// completed, whether it completes due to running to completion successfully, faulting due to an
1402         /// unhandled exception, or exiting out early due to being canceled.
1403         /// </para>
1404         /// <para>
1405         /// The <paramref name="continuationFunction"/>, when executed, should return a <see cref="Task{TNewResult}"/>.
1406         /// This task's completion state will be transferred to the task returned from the
1407         /// ContinueWith call.
1408         /// </para>
1409         /// </remarks>
1410         /// <exception cref="T:System.ArgumentNullException">
1411         /// The <paramref name="continuationFunction"/> argument is null.
1412         /// </exception>
1413         /// <exception cref="T:System.ArgumentOutOfRangeException">
1414         /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
1415         /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
1416         /// </exception>
1417         /// <exception cref="T:System.ArgumentNullException">
1418         /// The <paramref name="scheduler"/> argument is null.
1419         /// </exception>
1420         /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1421         /// has already been disposed.
1422         /// </exception>
1423         public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
1424             CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
1425         {
1426             return ContinueWith<TNewResult>(continuationFunction, state, scheduler, cancellationToken, continuationOptions);
1427         }
1428
1429         // Same as the above overload, just with a stack mark.
1430         internal Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
1431             TaskScheduler scheduler, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions)
1432         {
1433             if (continuationFunction == null)
1434             {
1435                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.continuationFunction);
1436             }
1437
1438             if (scheduler == null)
1439             {
1440                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler);
1441             }
1442
1443             TaskCreationOptions creationOptions;
1444             InternalTaskOptions internalOptions;
1445             CreationOptionsFromContinuationOptions(
1446                 continuationOptions,
1447                 out creationOptions,
1448                 out internalOptions);
1449
1450             Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
1451                 this, continuationFunction, state,
1452                 creationOptions, internalOptions
1453             );
1454
1455             // Register the continuation.  If synchronous execution is requested, this may
1456             // actually invoke the continuation before returning.
1457             ContinueWithCore(continuationFuture, scheduler, cancellationToken, continuationOptions);
1458
1459             return continuationFuture;
1460         }
1461
1462         #endregion
1463
1464         #endregion
1465     }
1466
1467     // Proxy class for better debugging experience
1468     internal class SystemThreadingTasks_FutureDebugView<TResult>
1469     {
1470         private Task<TResult> m_task;
1471
1472         public SystemThreadingTasks_FutureDebugView(Task<TResult> task)
1473         {
1474             m_task = task;
1475         }
1476
1477         public TResult Result { get { return m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default; } }
1478         public object AsyncState { get { return m_task.AsyncState; } }
1479         public TaskCreationOptions CreationOptions { get { return m_task.CreationOptions; } }
1480         public Exception Exception { get { return m_task.Exception; } }
1481         public int Id { get { return m_task.Id; } }
1482         public bool CancellationPending { get { return (m_task.Status == TaskStatus.WaitingToRun) && m_task.CancellationToken.IsCancellationRequested; } }
1483         public TaskStatus Status { get { return m_task.Status; } }
1484     }
1485 }