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