[bcl] Updates referencesource to 4.7.1
[mono-project.git] / mcs / class / referencesource / mscorlib / system / threading / Tasks / TaskFactory.cs
blobde78cb0b18239aafe6c7a8caab4112989cc0690c
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
7 //
8 // TaskFactory.cs
9 //
10 // <OWNER>Microsoft</OWNER>
12 // There are a plethora of common patterns for which Tasks are created. TaskFactory encodes
13 // these patterns into helper methods. These helpers also pick up default configuration settings
14 // applicable to the entire factory and configurable through its constructors.
16 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
18 using System;
19 using System.Collections.Generic;
20 using System.Security;
21 using System.Security.Permissions;
22 using System.Runtime.CompilerServices;
23 using System.Threading;
24 using System.Diagnostics.Contracts;
26 namespace System.Threading.Tasks
28 /// <summary>
29 /// Provides support for creating and scheduling
30 /// <see cref="T:System.Threading.Tasks.Task">Tasks</see>.
31 /// </summary>
32 /// <remarks>
33 /// <para>
34 /// There are many common patterns for which tasks are relevant. The <see cref="TaskFactory"/>
35 /// class encodes some of these patterns into methods that pick up default settings, which are
36 /// configurable through its constructors.
37 /// </para>
38 /// <para>
39 /// A default instance of <see cref="TaskFactory"/> is available through the
40 /// <see cref="System.Threading.Tasks.Task.Factory">Task.Factory</see> property.
41 /// </para>
42 /// </remarks>
43 [HostProtection(Synchronization = true, ExternalThreading = true)]
44 public class TaskFactory
46 // member variables
47 private CancellationToken m_defaultCancellationToken;
48 private TaskScheduler m_defaultScheduler;
49 private TaskCreationOptions m_defaultCreationOptions;
50 private TaskContinuationOptions m_defaultContinuationOptions;
53 private TaskScheduler DefaultScheduler
55 get
57 if (m_defaultScheduler == null) return TaskScheduler.Current;
58 else return m_defaultScheduler;
62 // sister method to above property -- avoids a TLS lookup
63 private TaskScheduler GetDefaultScheduler(Task currTask)
65 if (m_defaultScheduler != null) return m_defaultScheduler;
66 else if ((currTask != null)
67 && ((currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
69 return currTask.ExecutingTaskScheduler;
70 else return TaskScheduler.Default;
73 /* Constructors */
75 // ctor parameters provide defaults for the factory, which can be overridden by options provided to
76 // specific calls on the factory
79 /// <summary>
80 /// Initializes a <see cref="TaskFactory"/> instance with the default configuration.
81 /// </summary>
82 /// <remarks>
83 /// This constructor creates a <see cref="TaskFactory"/> instance with a default configuration. The
84 /// <see cref="TaskCreationOptions"/> property is initialized to
85 /// <see cref="System.Threading.Tasks.TaskCreationOptions.None">TaskCreationOptions.None</see>, the
86 /// <see cref="TaskContinuationOptions"/> property is initialized to <see
87 /// cref="System.Threading.Tasks.TaskContinuationOptions.None">TaskContinuationOptions.None</see>,
88 /// and the <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> property is
89 /// initialized to the current scheduler (see <see
90 /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>).
91 /// </remarks>
92 public TaskFactory()
93 : this(default(CancellationToken), TaskCreationOptions.None, TaskContinuationOptions.None, null)
97 /// <summary>
98 /// Initializes a <see cref="TaskFactory"/> instance with the specified configuration.
99 /// </summary>
100 /// <param name="cancellationToken">The default <see cref="CancellationToken"/> that will be assigned
101 /// to tasks created by this <see cref="TaskFactory"/> unless another CancellationToken is explicitly specified
102 /// while calling the factory methods.</param>
103 /// <remarks>
104 /// This constructor creates a <see cref="TaskFactory"/> instance with a default configuration. The
105 /// <see cref="TaskCreationOptions"/> property is initialized to
106 /// <see cref="System.Threading.Tasks.TaskCreationOptions.None">TaskCreationOptions.None</see>, the
107 /// <see cref="TaskContinuationOptions"/> property is initialized to <see
108 /// cref="System.Threading.Tasks.TaskContinuationOptions.None">TaskContinuationOptions.None</see>,
109 /// and the <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> property is
110 /// initialized to the current scheduler (see <see
111 /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>).
112 /// </remarks>
113 public TaskFactory(CancellationToken cancellationToken)
114 : this(cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
118 /// <summary>
119 /// Initializes a <see cref="TaskFactory"/> instance with the specified configuration.
120 /// </summary>
121 /// <param name="scheduler">
122 /// The <see cref="System.Threading.Tasks.TaskScheduler">
123 /// TaskScheduler</see> to use to schedule any tasks created with this TaskFactory. A null value
124 /// indicates that the current TaskScheduler should be used.
125 /// </param>
126 /// <remarks>
127 /// With this constructor, the
128 /// <see cref="TaskCreationOptions"/> property is initialized to
129 /// <see cref="System.Threading.Tasks.TaskCreationOptions.None">TaskCreationOptions.None</see>, the
130 /// <see cref="TaskContinuationOptions"/> property is initialized to <see
131 /// cref="System.Threading.Tasks.TaskContinuationOptions.None">TaskContinuationOptions.None</see>,
132 /// and the <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> property is
133 /// initialized to <paramref name="scheduler"/>, unless it's null, in which case the property is
134 /// initialized to the current scheduler (see <see
135 /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>).
136 /// </remarks>
137 public TaskFactory(TaskScheduler scheduler) // null means to use TaskScheduler.Current
138 : this(default(CancellationToken), TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
142 /// <summary>
143 /// Initializes a <see cref="TaskFactory"/> instance with the specified configuration.
144 /// </summary>
145 /// <param name="creationOptions">
146 /// The default <see cref="System.Threading.Tasks.TaskCreationOptions">
147 /// TaskCreationOptions</see> to use when creating tasks with this TaskFactory.
148 /// </param>
149 /// <param name="continuationOptions">
150 /// The default <see cref="System.Threading.Tasks.TaskContinuationOptions">
151 /// TaskContinuationOptions</see> to use when creating continuation tasks with this TaskFactory.
152 /// </param>
153 /// <exception cref="T:System.ArgumentOutOfRangeException">
154 /// The exception that is thrown when the
155 /// <paramref name="creationOptions"/> argument or the <paramref name="continuationOptions"/>
156 /// argument specifies an invalid value.
157 /// </exception>
158 /// <remarks>
159 /// With this constructor, the
160 /// <see cref="TaskCreationOptions"/> property is initialized to <paramref name="creationOptions"/>,
161 /// the
162 /// <see cref="TaskContinuationOptions"/> property is initialized to <paramref
163 /// name="continuationOptions"/>, and the <see
164 /// cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> property is initialized to the
165 /// current scheduler (see <see
166 /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>).
167 /// </remarks>
168 public TaskFactory(TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
169 : this(default(CancellationToken), creationOptions, continuationOptions, null)
173 /// <summary>
174 /// Initializes a <see cref="TaskFactory"/> instance with the specified configuration.
175 /// </summary>
176 /// <param name="cancellationToken">The default <see cref="CancellationToken"/> that will be assigned
177 /// to tasks created by this <see cref="TaskFactory"/> unless another CancellationToken is explicitly specified
178 /// while calling the factory methods.</param>
179 /// <param name="creationOptions">
180 /// The default <see cref="System.Threading.Tasks.TaskCreationOptions">
181 /// TaskCreationOptions</see> to use when creating tasks with this TaskFactory.
182 /// </param>
183 /// <param name="continuationOptions">
184 /// The default <see cref="System.Threading.Tasks.TaskContinuationOptions">
185 /// TaskContinuationOptions</see> to use when creating continuation tasks with this TaskFactory.
186 /// </param>
187 /// <param name="scheduler">
188 /// The default <see cref="System.Threading.Tasks.TaskScheduler">
189 /// TaskScheduler</see> to use to schedule any Tasks created with this TaskFactory. A null value
190 /// indicates that TaskScheduler.Current should be used.
191 /// </param>
192 /// <exception cref="T:System.ArgumentOutOfRangeException">
193 /// The exception that is thrown when the
194 /// <paramref name="creationOptions"/> argument or the <paramref name="continuationOptions"/>
195 /// argumentspecifies an invalid value.
196 /// </exception>
197 /// <remarks>
198 /// With this constructor, the
199 /// <see cref="TaskCreationOptions"/> property is initialized to <paramref name="creationOptions"/>,
200 /// the
201 /// <see cref="TaskContinuationOptions"/> property is initialized to <paramref
202 /// name="continuationOptions"/>, and the <see
203 /// cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> property is initialized to
204 /// <paramref name="scheduler"/>, unless it's null, in which case the property is initialized to the
205 /// current scheduler (see <see
206 /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>).
207 /// </remarks>
208 public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
210 CheckMultiTaskContinuationOptions(continuationOptions);
211 CheckCreationOptions(creationOptions);
213 m_defaultCancellationToken = cancellationToken;
214 m_defaultScheduler = scheduler;
215 m_defaultCreationOptions = creationOptions;
216 m_defaultContinuationOptions = continuationOptions;
219 [ContractArgumentValidatorAttribute]
220 internal static void CheckCreationOptions(TaskCreationOptions creationOptions)
222 // Check for validity of options
223 if ((creationOptions &
224 ~(TaskCreationOptions.AttachedToParent |
225 TaskCreationOptions.DenyChildAttach |
226 TaskCreationOptions.HideScheduler |
227 TaskCreationOptions.LongRunning |
228 TaskCreationOptions.PreferFairness |
229 TaskCreationOptions.RunContinuationsAsynchronously)) != 0)
231 throw new ArgumentOutOfRangeException("creationOptions");
233 Contract.EndContractBlock();
236 /* Properties */
238 /// <summary>
239 /// Gets the default <see cref="System.Threading.CancellationToken">CancellationToken</see> of this
240 /// TaskFactory.
241 /// </summary>
242 /// <remarks>
243 /// This property returns the default <see cref="CancellationToken"/> that will be assigned to all
244 /// tasks created by this factory unless another CancellationToken value is explicitly specified
245 /// during the call to the factory methods.
246 /// </remarks>
247 public CancellationToken CancellationToken { get { return m_defaultCancellationToken; } }
249 /// <summary>
250 /// Gets the <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> of this
251 /// TaskFactory.
252 /// </summary>
253 /// <remarks>
254 /// This property returns the default scheduler for this factory. It will be used to schedule all
255 /// tasks unless another scheduler is explicitly specified during calls to this factory's methods.
256 /// If null, <see cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>
257 /// will be used.
258 /// </remarks>
259 public TaskScheduler Scheduler { get { return m_defaultScheduler; } }
261 /// <summary>
262 /// Gets the <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions
263 /// </see> value of this TaskFactory.
264 /// </summary>
265 /// <remarks>
266 /// This property returns the default creation options for this factory. They will be used to create all
267 /// tasks unless other options are explicitly specified during calls to this factory's methods.
268 /// </remarks>
269 public TaskCreationOptions CreationOptions { get { return m_defaultCreationOptions; } }
271 /// <summary>
272 /// Gets the <see cref="System.Threading.Tasks.TaskCreationOptions">TaskContinuationOptions
273 /// </see> value of this TaskFactory.
274 /// </summary>
275 /// <remarks>
276 /// This property returns the default continuation options for this factory. They will be used to create
277 /// all continuation tasks unless other options are explicitly specified during calls to this factory's methods.
278 /// </remarks>
279 public TaskContinuationOptions ContinuationOptions { get { return m_defaultContinuationOptions; } }
282 // StartNew methods
285 /// <summary>
286 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
287 /// </summary>
288 /// <param name="action">The action delegate to execute asynchronously.</param>
289 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
290 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref name="action"/>
291 /// argument is null.</exception>
292 /// <remarks>
293 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors
294 /// and then calling
295 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution. However,
296 /// unless creation and scheduling must be separated, StartNew is the recommended
297 /// approach for both simplicity and performance.
298 /// </remarks>
299 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
300 public Task StartNew(Action action)
302 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
303 Task currTask = Task.InternalCurrent;
304 return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask),
305 m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
308 /// <summary>
309 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
310 /// </summary>
311 /// <param name="action">The action delegate to execute asynchronously.</param>
312 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
313 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
314 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref name="action"/>
315 /// argument is null.</exception>
316 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
317 /// has already been disposed.
318 /// </exception>
319 /// <remarks>
320 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors
321 /// and then calling
322 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution. However,
323 /// unless creation and scheduling must be separated, StartNew is the recommended
324 /// approach for both simplicity and performance.
325 /// </remarks>
326 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
327 public Task StartNew(Action action, CancellationToken cancellationToken)
329 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
330 Task currTask = Task.InternalCurrent;
331 return Task.InternalStartNew(currTask, action, null, cancellationToken, GetDefaultScheduler(currTask),
332 m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
335 /// <summary>
336 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
337 /// </summary>
338 /// <param name="action">The action delegate to execute asynchronously.</param>
339 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
340 /// created
341 /// <see cref="T:System.Threading.Tasks.Task">Task.</see></param>
342 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
343 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
344 /// name="action"/>
345 /// argument is null.</exception>
346 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
347 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
348 /// value.</exception>
349 /// <remarks>
350 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
351 /// then calling
352 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
353 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
354 /// for both simplicity and performance.
355 /// </remarks>
356 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
357 public Task StartNew(Action action, TaskCreationOptions creationOptions)
359 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
360 Task currTask = Task.InternalCurrent;
361 return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask), creationOptions,
362 InternalTaskOptions.None, ref stackMark);
365 /// <summary>
366 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
367 /// </summary>
368 /// <param name="action">The action delegate to execute asynchronously.</param>
369 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/></param>
370 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
371 /// created
372 /// <see cref="T:System.Threading.Tasks.Task">Task.</see></param>
373 /// <param name="scheduler">The <see
374 /// cref="T:System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
375 /// that is used to schedule the created <see
376 /// cref="T:System.Threading.Tasks.Task">Task</see>.</param>
377 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
378 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
379 /// name="action"/>
380 /// argument is null.</exception>
381 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
382 /// name="scheduler"/>
383 /// argument is null.</exception>
384 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
385 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
386 /// value.</exception>
387 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
388 /// has already been disposed.
389 /// </exception>
390 /// <remarks>
391 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
392 /// then calling
393 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
394 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
395 /// for both simplicity and performance.
396 /// </remarks>
397 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
398 public Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
400 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
401 return Task.InternalStartNew(
402 Task.InternalCurrentIfAttached(creationOptions), action, null, cancellationToken, scheduler, creationOptions,
403 InternalTaskOptions.None, ref stackMark);
406 // Internal version includes InternalTaskOptions for Parallel.Invoke() support.
407 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
408 internal Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
410 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
411 return Task.InternalStartNew(
412 Task.InternalCurrentIfAttached(creationOptions), action, null, cancellationToken, scheduler, creationOptions, internalOptions, ref stackMark);
416 /// <summary>
417 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
418 /// </summary>
419 /// <param name="action">The action delegate to execute asynchronously.</param>
420 /// <param name="state">An object containing data to be used by the <paramref name="action"/>
421 /// delegate.</param>
422 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
423 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
424 /// name="action"/>
425 /// argument is null.</exception>
426 /// <remarks>
427 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
428 /// then calling
429 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
430 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
431 /// for both simplicity and performance.
432 /// </remarks>
433 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
434 public Task StartNew(Action<Object> action, Object state)
436 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
437 Task currTask = Task.InternalCurrent;
438 return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
439 m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
443 /// <summary>
444 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
445 /// </summary>
446 /// <param name="action">The action delegate to execute asynchronously.</param>
447 /// <param name="state">An object containing data to be used by the <paramref name="action"/>
448 /// delegate.</param>
449 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/></param>
450 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
451 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
452 /// name="action"/>
453 /// argument is null.</exception>
454 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
455 /// has already been disposed.
456 /// </exception>
457 /// <remarks>
458 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
459 /// then calling
460 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
461 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
462 /// for both simplicity and performance.
463 /// </remarks>
464 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
465 public Task StartNew(Action<Object> action, Object state, CancellationToken cancellationToken)
467 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
468 Task currTask = Task.InternalCurrent;
469 return Task.InternalStartNew(currTask, action, state, cancellationToken, GetDefaultScheduler(currTask),
470 m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
473 /// <summary>
474 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
475 /// </summary>
476 /// <param name="action">The action delegate to execute asynchronously.</param>
477 /// <param name="state">An object containing data to be used by the <paramref name="action"/>
478 /// delegate.</param>
479 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
480 /// created
481 /// <see cref="T:System.Threading.Tasks.Task">Task.</see></param>
482 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
483 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
484 /// name="action"/>
485 /// argument is null.</exception>
486 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
487 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
488 /// value.</exception>
489 /// <remarks>
490 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
491 /// then calling
492 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
493 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
494 /// for both simplicity and performance.
495 /// </remarks>
496 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
497 public Task StartNew(Action<Object> action, Object state, TaskCreationOptions creationOptions)
499 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
500 Task currTask = Task.InternalCurrent;
501 return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
502 creationOptions, InternalTaskOptions.None, ref stackMark);
505 /// <summary>
506 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task">Task</see>.
507 /// </summary>
508 /// <param name="action">The action delegate to execute asynchronously.</param>
509 /// <param name="state">An object containing data to be used by the <paramref name="action"/>
510 /// delegate.</param>
511 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
512 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
513 /// created
514 /// <see cref="T:System.Threading.Tasks.Task">Task.</see></param>
515 /// <param name="scheduler">The <see
516 /// cref="T:System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
517 /// that is used to schedule the created <see
518 /// cref="T:System.Threading.Tasks.Task">Task</see>.</param>
519 /// <returns>The started <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
520 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
521 /// name="action"/>
522 /// argument is null.</exception>
523 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
524 /// name="scheduler"/>
525 /// argument is null.</exception>
526 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
527 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
528 /// value.</exception>
529 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
530 /// has already been disposed.
531 /// </exception>
532 /// <remarks>
533 /// Calling StartNew is functionally equivalent to creating a Task using one of its constructors and
534 /// then calling
535 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
536 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
537 /// for both simplicity and performance.
538 /// </remarks>
539 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
540 public Task StartNew(Action<Object> action, Object state, CancellationToken cancellationToken,
541 TaskCreationOptions creationOptions, TaskScheduler scheduler)
543 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
544 return Task.InternalStartNew(
545 Task.InternalCurrentIfAttached(creationOptions), action, state, cancellationToken, scheduler,
546 creationOptions, InternalTaskOptions.None, ref stackMark);
549 /// <summary>
550 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
551 /// </summary>
552 /// <typeparam name="TResult">The type of the result available through the
553 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
554 /// </typeparam>
555 /// <param name="function">A function delegate that returns the future result to be available through
556 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
557 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
558 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
559 /// name="function"/>
560 /// argument is null.</exception>
561 /// <remarks>
562 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
563 /// of its constructors and then calling
564 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
565 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
566 /// for both simplicity and performance.
567 /// </remarks>
568 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
569 public Task<TResult> StartNew<TResult>(Func<TResult> function)
571 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
572 Task currTask = Task.InternalCurrent;
573 return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken,
574 m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
578 /// <summary>
579 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
580 /// </summary>
581 /// <typeparam name="TResult">The type of the result available through the
582 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
583 /// </typeparam>
584 /// <param name="function">A function delegate that returns the future result to be available through
585 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
586 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/></param>
587 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
588 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
589 /// name="function"/>
590 /// argument is null.</exception>
591 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
592 /// has already been disposed.
593 /// </exception>
594 /// <remarks>
595 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
596 /// of its constructors and then calling
597 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
598 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
599 /// for both simplicity and performance.
600 /// </remarks>
601 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
602 public Task<TResult> StartNew<TResult>(Func<TResult> function, CancellationToken cancellationToken)
604 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
605 Task currTask = Task.InternalCurrent;
606 return Task<TResult>.StartNew(currTask, function, cancellationToken,
607 m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
610 /// <summary>
611 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
612 /// </summary>
613 /// <typeparam name="TResult">The type of the result available through the
614 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
615 /// </typeparam>
616 /// <param name="function">A function delegate that returns the future result to be available through
617 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
618 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
619 /// created
620 /// <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
621 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
622 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
623 /// name="function"/>
624 /// argument is null.</exception>
625 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
626 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
627 /// value.</exception>
628 /// <remarks>
629 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
630 /// of its constructors and then calling
631 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
632 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
633 /// for both simplicity and performance.
634 /// </remarks>
635 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
636 public Task<TResult> StartNew<TResult>(Func<TResult> function, TaskCreationOptions creationOptions)
638 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
639 Task currTask = Task.InternalCurrent;
640 return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken,
641 creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
644 /// <summary>
645 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
646 /// </summary>
647 /// <typeparam name="TResult">The type of the result available through the
648 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
649 /// </typeparam>
650 /// <param name="function">A function delegate that returns the future result to be available through
651 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
652 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
653 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
654 /// created
655 /// <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
656 /// <param name="scheduler">The <see
657 /// cref="T:System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
658 /// that is used to schedule the created <see cref="T:System.Threading.Tasks.Task{TResult}">
659 /// Task{TResult}</see>.</param>
660 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
661 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
662 /// name="function"/>
663 /// argument is null.</exception>
664 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
665 /// name="scheduler"/>
666 /// argument is null.</exception>
667 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
668 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
669 /// value.</exception>
670 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
671 /// has already been disposed.
672 /// </exception>
673 /// <remarks>
674 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
675 /// of its constructors and then calling
676 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
677 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
678 /// for both simplicity and performance.
679 /// </remarks>
680 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
681 public Task<TResult> StartNew<TResult>(Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
683 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
684 return Task<TResult>.StartNew(
685 Task.InternalCurrentIfAttached(creationOptions), function, cancellationToken,
686 creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
689 /// <summary>
690 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
691 /// </summary>
692 /// <typeparam name="TResult">The type of the result available through the
693 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
694 /// </typeparam>
695 /// <param name="function">A function delegate that returns the future result to be available through
696 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
697 /// <param name="state">An object containing data to be used by the <paramref name="function"/>
698 /// delegate.</param>
699 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
700 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
701 /// name="function"/>
702 /// argument is null.</exception>
703 /// <remarks>
704 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
705 /// of its constructors and then calling
706 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
707 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
708 /// for both simplicity and performance.
709 /// </remarks>
710 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
711 public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state)
713 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
714 Task currTask = Task.InternalCurrent;
715 return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
716 m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
720 /// <summary>
721 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
722 /// </summary>
723 /// <typeparam name="TResult">The type of the result available through the
724 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
725 /// </typeparam>
726 /// <param name="function">A function delegate that returns the future result to be available through
727 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
728 /// <param name="state">An object containing data to be used by the <paramref name="function"/>
729 /// delegate.</param>
730 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/></param>
731 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
732 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
733 /// name="function"/>
734 /// argument is null.</exception>
735 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
736 /// has already been disposed.
737 /// </exception>
738 /// <remarks>
739 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
740 /// of its constructors and then calling
741 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
742 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
743 /// for both simplicity and performance.
744 /// </remarks>
745 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
746 public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, CancellationToken cancellationToken)
748 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
749 Task currTask = Task.InternalCurrent;
750 return Task<TResult>.StartNew(currTask, function, state, cancellationToken,
751 m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
754 /// <summary>
755 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
756 /// </summary>
757 /// <typeparam name="TResult">The type of the result available through the
758 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
759 /// </typeparam>
760 /// <param name="function">A function delegate that returns the future result to be available through
761 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
762 /// <param name="state">An object containing data to be used by the <paramref name="function"/>
763 /// delegate.</param>
764 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
765 /// created
766 /// <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
767 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
768 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
769 /// name="function"/>
770 /// argument is null.</exception>
771 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
772 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
773 /// value.</exception>
774 /// <remarks>
775 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
776 /// of its constructors and then calling
777 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
778 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
779 /// for both simplicity and performance.
780 /// </remarks>
781 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
782 public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, TaskCreationOptions creationOptions)
784 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
785 Task currTask = Task.InternalCurrent;
786 return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
787 creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
790 /// <summary>
791 /// Creates and starts a <see cref="T:System.Threading.Tasks.Task{TResult}"/>.
792 /// </summary>
793 /// <typeparam name="TResult">The type of the result available through the
794 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
795 /// </typeparam>
796 /// <param name="function">A function delegate that returns the future result to be available through
797 /// the <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
798 /// <param name="state">An object containing data to be used by the <paramref name="function"/>
799 /// delegate.</param>
800 /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new task.</param>
801 /// <param name="creationOptions">A TaskCreationOptions value that controls the behavior of the
802 /// created
803 /// <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
804 /// <param name="scheduler">The <see
805 /// cref="T:System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
806 /// that is used to schedule the created <see cref="T:System.Threading.Tasks.Task{TResult}">
807 /// Task{TResult}</see>.</param>
808 /// <returns>The started <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
809 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
810 /// name="function"/>
811 /// argument is null.</exception>
812 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the <paramref
813 /// name="scheduler"/>
814 /// argument is null.</exception>
815 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
816 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
817 /// value.</exception>
818 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
819 /// has already been disposed.
820 /// </exception>
821 /// <remarks>
822 /// Calling StartNew is functionally equivalent to creating a <see cref="Task{TResult}"/> using one
823 /// of its constructors and then calling
824 /// <see cref="System.Threading.Tasks.Task.Start()">Start</see> to schedule it for execution.
825 /// However, unless creation and scheduling must be separated, StartNew is the recommended approach
826 /// for both simplicity and performance.
827 /// </remarks>
828 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
829 public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, CancellationToken cancellationToken,
830 TaskCreationOptions creationOptions, TaskScheduler scheduler)
832 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
833 return Task<TResult>.StartNew(
834 Task.InternalCurrentIfAttached(creationOptions), function, state, cancellationToken,
835 creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
839 // FromAsync methods
842 /// <summary>
843 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that executes an end method action
844 /// when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
845 /// </summary>
846 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
847 /// <paramref name="endMethod"/>.</param>
848 /// <param name="endMethod">The action delegate that processes the completed <paramref
849 /// name="asyncResult"/>.</param>
850 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
851 /// <paramref name="asyncResult"/> argument is null.</exception>
852 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
853 /// <paramref name="endMethod"/> argument is null.</exception>
854 /// <returns>A <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the asynchronous
855 /// operation.</returns>
856 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
857 public Task FromAsync(
858 IAsyncResult asyncResult,
859 Action<IAsyncResult> endMethod)
861 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
862 return FromAsync(asyncResult, endMethod, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
865 /// <summary>
866 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that executes an end method action
867 /// when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
868 /// </summary>
869 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
870 /// <paramref name="endMethod"/>.</param>
871 /// <param name="endMethod">The action delegate that processes the completed <paramref
872 /// name="asyncResult"/>.</param>
873 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
874 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
875 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
876 /// <paramref name="asyncResult"/> argument is null.</exception>
877 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
878 /// <paramref name="endMethod"/> argument is null.</exception>
879 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
880 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
881 /// value.</exception>
882 /// <returns>A <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the asynchronous
883 /// operation.</returns>
884 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
885 public Task FromAsync(
886 IAsyncResult asyncResult,
887 Action<IAsyncResult> endMethod,
888 TaskCreationOptions creationOptions)
890 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
891 return FromAsync(asyncResult, endMethod, creationOptions, DefaultScheduler, ref stackMark);
894 /// <summary>
895 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that executes an end method action
896 /// when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
897 /// </summary>
898 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
899 /// <paramref name="endMethod"/>.</param>
900 /// <param name="endMethod">The action delegate that processes the completed <paramref
901 /// name="asyncResult"/>.</param>
902 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
903 /// that is used to schedule the task that executes the end method.</param>
904 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
905 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
906 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
907 /// <paramref name="asyncResult"/> argument is null.</exception>
908 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
909 /// <paramref name="endMethod"/> argument is null.</exception>
910 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
911 /// <paramref name="scheduler"/> argument is null.</exception>
912 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
913 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
914 /// value.</exception>
915 /// <returns>A <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the asynchronous
916 /// operation.</returns>
917 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
918 public Task FromAsync(
919 IAsyncResult asyncResult,
920 Action<IAsyncResult> endMethod,
921 TaskCreationOptions creationOptions,
922 TaskScheduler scheduler)
924 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
925 return FromAsync(asyncResult, endMethod, creationOptions, scheduler, ref stackMark);
928 // private version that supports StackCrawlMark.
929 private Task FromAsync(
930 IAsyncResult asyncResult,
931 Action<IAsyncResult> endMethod,
932 TaskCreationOptions creationOptions,
933 TaskScheduler scheduler,
934 ref StackCrawlMark stackMark)
936 return TaskFactory<VoidTaskResult>.FromAsyncImpl(asyncResult, null, endMethod, creationOptions, scheduler, ref stackMark);
939 /// <summary>
940 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
941 /// and end methods that conform to the Asynchronous Programming Model pattern.
942 /// </summary>
943 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
944 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
945 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
946 /// delegate.</param>
947 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
948 /// <paramref name="beginMethod"/> argument is null.</exception>
949 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
950 /// <paramref name="endMethod"/> argument is null.</exception>
951 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
952 /// asynchronous operation.</returns>
953 /// <remarks>
954 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
955 /// </remarks>
956 public Task FromAsync(
957 Func<AsyncCallback, object, IAsyncResult> beginMethod,
958 Action<IAsyncResult> endMethod,
959 object state)
961 return FromAsync(beginMethod, endMethod, state, m_defaultCreationOptions);
964 /// <summary>
965 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
966 /// and end methods that conform to the Asynchronous Programming Model pattern.
967 /// </summary>
968 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
969 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
970 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
971 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
972 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
973 /// delegate.</param>
974 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
975 /// <paramref name="beginMethod"/> argument is null.</exception>
976 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
977 /// <paramref name="endMethod"/> argument is null.</exception>
978 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
979 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
980 /// value.</exception>
981 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
982 /// asynchronous operation.</returns>
983 /// <remarks>
984 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
985 /// </remarks>
986 public Task FromAsync(
987 Func<AsyncCallback, object, IAsyncResult> beginMethod,
988 Action<IAsyncResult> endMethod, object state, TaskCreationOptions creationOptions)
990 return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, state, creationOptions);
993 /// <summary>
994 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
995 /// and end methods that conform to the Asynchronous Programming Model pattern.
996 /// </summary>
997 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
998 /// name="beginMethod"/>
999 /// delegate.</typeparam>
1000 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1001 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1002 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1003 /// delegate.</param>
1004 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1005 /// delegate.</param>
1006 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1007 /// <paramref name="beginMethod"/> argument is null.</exception>
1008 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1009 /// <paramref name="endMethod"/> argument is null.</exception>
1010 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1011 /// asynchronous operation.</returns>
1012 /// <remarks>
1013 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1014 /// </remarks>
1015 public Task FromAsync<TArg1>(
1016 Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
1017 Action<IAsyncResult> endMethod,
1018 TArg1 arg1,
1019 object state)
1021 return FromAsync(beginMethod, endMethod, arg1, state, m_defaultCreationOptions);
1024 /// <summary>
1025 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
1026 /// and end methods that conform to the Asynchronous Programming Model pattern.
1027 /// </summary>
1028 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1029 /// name="beginMethod"/>
1030 /// delegate.</typeparam>
1031 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1032 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1033 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1034 /// delegate.</param>
1035 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1036 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1037 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1038 /// delegate.</param>
1039 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1040 /// <paramref name="beginMethod"/> argument is null.</exception>
1041 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1042 /// <paramref name="endMethod"/> argument is null.</exception>
1043 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1044 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1045 /// value.</exception>
1046 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1047 /// asynchronous operation.</returns>
1048 /// <remarks>
1049 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1050 /// </remarks>
1051 public Task FromAsync<TArg1>(
1052 Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
1053 Action<IAsyncResult> endMethod,
1054 TArg1 arg1, object state, TaskCreationOptions creationOptions)
1056 return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, state, creationOptions);
1059 /// <summary>
1060 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
1061 /// and end methods that conform to the Asynchronous Programming Model pattern.
1062 /// </summary>
1063 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1064 /// name="beginMethod"/>
1065 /// delegate.</typeparam>
1066 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1067 /// delegate.</typeparam>
1068 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1069 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1070 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1071 /// delegate.</param>
1072 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1073 /// delegate.</param>
1074 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1075 /// delegate.</param>
1076 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1077 /// <paramref name="beginMethod"/> argument is null.</exception>
1078 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1079 /// <paramref name="endMethod"/> argument is null.</exception>
1080 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1081 /// asynchronous operation.</returns>
1082 /// <remarks>
1083 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1084 /// </remarks>
1085 public Task FromAsync<TArg1, TArg2>(
1086 Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
1087 Action<IAsyncResult> endMethod,
1088 TArg1 arg1, TArg2 arg2, object state)
1090 return FromAsync(beginMethod, endMethod, arg1, arg2, state, m_defaultCreationOptions);
1093 /// <summary>
1094 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
1095 /// and end methods that conform to the Asynchronous Programming Model pattern.
1096 /// </summary>
1097 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1098 /// name="beginMethod"/>
1099 /// delegate.</typeparam>
1100 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1101 /// delegate.</typeparam>
1102 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1103 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1104 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1105 /// delegate.</param>
1106 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1107 /// delegate.</param>
1108 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1109 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1110 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1111 /// delegate.</param>
1112 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1113 /// <paramref name="beginMethod"/> argument is null.</exception>
1114 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1115 /// <paramref name="endMethod"/> argument is null.</exception>
1116 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1117 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1118 /// value.</exception>
1119 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1120 /// asynchronous operation.</returns>
1121 /// <remarks>
1122 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1123 /// </remarks>
1124 public Task FromAsync<TArg1, TArg2>(
1125 Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
1126 Action<IAsyncResult> endMethod,
1127 TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
1129 return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, arg2, state, creationOptions);
1132 /// <summary>
1133 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
1134 /// and end methods that conform to the Asynchronous Programming Model pattern.
1135 /// </summary>
1136 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1137 /// name="beginMethod"/>
1138 /// delegate.</typeparam>
1139 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1140 /// delegate.</typeparam>
1141 /// <typeparam name="TArg3">The type of the third argument passed to <paramref name="beginMethod"/>
1142 /// delegate.</typeparam>
1143 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1144 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1145 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1146 /// delegate.</param>
1147 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1148 /// delegate.</param>
1149 /// <param name="arg3">The third argument passed to the <paramref name="beginMethod"/>
1150 /// delegate.</param>
1151 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1152 /// delegate.</param>
1153 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1154 /// <paramref name="beginMethod"/> argument is null.</exception>
1155 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1156 /// <paramref name="endMethod"/> argument is null.</exception>
1157 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1158 /// asynchronous operation.</returns>
1159 /// <remarks>
1160 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1161 /// </remarks>
1162 public Task FromAsync<TArg1, TArg2, TArg3>(
1163 Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod,
1164 Action<IAsyncResult> endMethod,
1165 TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
1167 return FromAsync(beginMethod, endMethod, arg1, arg2, arg3, state, m_defaultCreationOptions);
1170 /// <summary>
1171 /// Creates a <see cref="T:System.Threading.Tasks.Task">Task</see> that represents a pair of begin
1172 /// and end methods that conform to the Asynchronous Programming Model pattern.
1173 /// </summary>
1174 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1175 /// name="beginMethod"/>
1176 /// delegate.</typeparam>
1177 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1178 /// delegate.</typeparam>
1179 /// <typeparam name="TArg3">The type of the third argument passed to <paramref name="beginMethod"/>
1180 /// delegate.</typeparam>
1181 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1182 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1183 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1184 /// delegate.</param>
1185 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1186 /// delegate.</param>
1187 /// <param name="arg3">The third argument passed to the <paramref name="beginMethod"/>
1188 /// delegate.</param>
1189 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1190 /// created <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1191 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1192 /// delegate.</param>
1193 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1194 /// <paramref name="beginMethod"/> argument is null.</exception>
1195 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1196 /// <paramref name="endMethod"/> argument is null.</exception>
1197 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1198 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1199 /// value.</exception>
1200 /// <returns>The created <see cref="T:System.Threading.Tasks.Task">Task</see> that represents the
1201 /// asynchronous operation.</returns>
1202 /// <remarks>
1203 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1204 /// </remarks>
1205 public Task FromAsync<TArg1, TArg2, TArg3>(
1206 Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod,
1207 Action<IAsyncResult> endMethod,
1208 TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
1210 return TaskFactory<VoidTaskResult>.FromAsyncImpl<TArg1, TArg2, TArg3>(beginMethod, null, endMethod, arg1, arg2, arg3, state, creationOptions);
1214 // Additional FromAsync() overloads used for inferencing convenience
1217 /// <summary>
1218 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that executes an end
1219 /// method function when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
1220 /// </summary>
1221 /// <typeparam name="TResult">The type of the result available through the
1222 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1223 /// </typeparam>
1224 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
1225 /// <paramref name="endMethod"/>.</param>
1226 /// <param name="endMethod">The function delegate that processes the completed <paramref
1227 /// name="asyncResult"/>.</param>
1228 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1229 /// <paramref name="asyncResult"/> argument is null.</exception>
1230 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1231 /// <paramref name="endMethod"/> argument is null.</exception>
1232 /// <returns>A <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents the
1233 /// asynchronous operation.</returns>
1234 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1235 public Task<TResult> FromAsync<TResult>(
1236 IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
1238 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1239 return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
1242 /// <summary>
1243 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that executes an end
1244 /// method function when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
1245 /// </summary>
1246 /// <typeparam name="TResult">The type of the result available through the
1247 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1248 /// </typeparam>
1249 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
1250 /// <paramref name="endMethod"/>.</param>
1251 /// <param name="endMethod">The function delegate that processes the completed <paramref
1252 /// name="asyncResult"/>.</param>
1253 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1254 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1255 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1256 /// <paramref name="asyncResult"/> argument is null.</exception>
1257 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1258 /// <paramref name="endMethod"/> argument is null.</exception>
1259 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1260 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1261 /// value.</exception>
1262 /// <returns>A <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents the
1263 /// asynchronous operation.</returns>
1264 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1265 public Task<TResult> FromAsync<TResult>(
1266 IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
1268 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1269 return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, creationOptions, DefaultScheduler, ref stackMark);
1272 /// <summary>
1273 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that executes an end
1274 /// method function when a specified <see cref="T:System.IAsyncResult">IAsyncResult</see> completes.
1275 /// </summary>
1276 /// <typeparam name="TResult">The type of the result available through the
1277 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1278 /// </typeparam>
1279 /// <param name="asyncResult">The IAsyncResult whose completion should trigger the processing of the
1280 /// <paramref name="endMethod"/>.</param>
1281 /// <param name="endMethod">The function delegate that processes the completed <paramref
1282 /// name="asyncResult"/>.</param>
1283 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
1284 /// that is used to schedule the task that executes the end method.</param>
1285 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1286 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1287 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1288 /// <paramref name="asyncResult"/> argument is null.</exception>
1289 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1290 /// <paramref name="endMethod"/> argument is null.</exception>
1291 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1292 /// <paramref name="scheduler"/> argument is null.</exception>
1293 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1294 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1295 /// value.</exception>
1296 /// <returns>A <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents the
1297 /// asynchronous operation.</returns>
1298 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1299 public Task<TResult> FromAsync<TResult>(
1300 IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
1302 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1303 return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, creationOptions, scheduler, ref stackMark);
1306 /// <summary>
1307 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1308 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1309 /// </summary>
1310 /// <typeparam name="TResult">The type of the result available through the
1311 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1312 /// </typeparam>
1313 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1314 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1315 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1316 /// delegate.</param>
1317 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1318 /// <paramref name="beginMethod"/> argument is null.</exception>
1319 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1320 /// <paramref name="endMethod"/> argument is null.</exception>
1321 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1322 /// represents the asynchronous operation.</returns>
1323 /// <remarks>
1324 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1325 /// </remarks>
1326 public Task<TResult> FromAsync<TResult>(
1327 Func<AsyncCallback, object, IAsyncResult> beginMethod,
1328 Func<IAsyncResult, TResult> endMethod, object state)
1330 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, m_defaultCreationOptions);
1333 /// <summary>
1334 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1335 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1336 /// </summary>
1337 /// <typeparam name="TResult">The type of the result available through the
1338 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1339 /// </typeparam>
1340 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1341 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1342 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1343 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1344 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1345 /// delegate.</param>
1346 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1347 /// <paramref name="beginMethod"/> argument is null.</exception>
1348 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1349 /// <paramref name="endMethod"/> argument is null.</exception>
1350 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1351 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1352 /// value.</exception>
1353 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1354 /// represents the asynchronous operation.</returns>
1355 /// <remarks>
1356 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1357 /// </remarks>
1358 public Task<TResult> FromAsync<TResult>(
1359 Func<AsyncCallback, object, IAsyncResult> beginMethod,
1360 Func<IAsyncResult, TResult> endMethod, object state, TaskCreationOptions creationOptions)
1362 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, creationOptions);
1365 /// <summary>
1366 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1367 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1368 /// </summary>
1369 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1370 /// name="beginMethod"/> delegate.</typeparam>
1371 /// <typeparam name="TResult">The type of the result available through the
1372 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1373 /// </typeparam>
1374 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1375 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1376 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1377 /// delegate.</param>
1378 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1379 /// delegate.</param>
1380 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1381 /// <paramref name="beginMethod"/> argument is null.</exception>
1382 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1383 /// <paramref name="endMethod"/> argument is null.</exception>
1384 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1385 /// represents the asynchronous operation.</returns>
1386 /// <remarks>
1387 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1388 /// </remarks>
1389 public Task<TResult> FromAsync<TArg1, TResult>(
1390 Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
1391 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state)
1393 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, m_defaultCreationOptions);
1396 /// <summary>
1397 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1398 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1399 /// </summary>
1400 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1401 /// name="beginMethod"/> delegate.</typeparam>
1402 /// <typeparam name="TResult">The type of the result available through the
1403 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1404 /// </typeparam>
1405 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1406 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1407 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1408 /// delegate.</param>
1409 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1410 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1411 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1412 /// delegate.</param>
1413 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1414 /// <paramref name="beginMethod"/> argument is null.</exception>
1415 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1416 /// <paramref name="endMethod"/> argument is null.</exception>
1417 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1418 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1419 /// value.</exception>
1420 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1421 /// represents the asynchronous operation.</returns>
1422 /// <remarks>
1423 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1424 /// </remarks>
1425 public Task<TResult> FromAsync<TArg1, TResult>(Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
1426 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state, TaskCreationOptions creationOptions)
1428 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, creationOptions);
1431 /// <summary>
1432 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1433 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1434 /// </summary>
1435 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1436 /// name="beginMethod"/> delegate.</typeparam>
1437 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1438 /// delegate.</typeparam>
1439 /// <typeparam name="TResult">The type of the result available through the
1440 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1441 /// </typeparam>
1442 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1443 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1444 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1445 /// delegate.</param>
1446 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1447 /// delegate.</param>
1448 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1449 /// delegate.</param>
1450 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1451 /// <paramref name="beginMethod"/> argument is null.</exception>
1452 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1453 /// <paramref name="endMethod"/> argument is null.</exception>
1454 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1455 /// represents the asynchronous operation.</returns>
1456 /// <remarks>
1457 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1458 /// </remarks>
1459 public Task<TResult> FromAsync<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
1460 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state)
1462 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, m_defaultCreationOptions);
1465 /// <summary>
1466 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1467 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1468 /// </summary>
1469 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1470 /// name="beginMethod"/> delegate.</typeparam>
1471 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1472 /// delegate.</typeparam>
1473 /// <typeparam name="TResult">The type of the result available through the
1474 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1475 /// </typeparam>
1476 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1477 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1478 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1479 /// delegate.</param>
1480 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1481 /// delegate.</param>
1482 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1483 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1484 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1485 /// delegate.</param>
1486 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1487 /// <paramref name="beginMethod"/> argument is null.</exception>
1488 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1489 /// <paramref name="endMethod"/> argument is null.</exception>
1490 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1491 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1492 /// value.</exception>
1493 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1494 /// represents the asynchronous operation.</returns>
1495 /// <remarks>
1496 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1497 /// </remarks>
1498 public Task<TResult> FromAsync<TArg1, TArg2, TResult>(
1499 Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
1500 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
1502 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, creationOptions);
1505 /// <summary>
1506 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1507 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1508 /// </summary>
1509 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1510 /// name="beginMethod"/> delegate.</typeparam>
1511 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1512 /// delegate.</typeparam>
1513 /// <typeparam name="TArg3">The type of the third argument passed to <paramref name="beginMethod"/>
1514 /// delegate.</typeparam>
1515 /// <typeparam name="TResult">The type of the result available through the
1516 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1517 /// </typeparam>
1518 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1519 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1520 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1521 /// delegate.</param>
1522 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1523 /// delegate.</param>
1524 /// <param name="arg3">The third argument passed to the <paramref name="beginMethod"/>
1525 /// delegate.</param>
1526 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1527 /// delegate.</param>
1528 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1529 /// <paramref name="beginMethod"/> argument is null.</exception>
1530 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1531 /// <paramref name="endMethod"/> argument is null.</exception>
1532 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1533 /// represents the asynchronous operation.</returns>
1534 /// <remarks>
1535 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1536 /// </remarks>
1537 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>(
1538 Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod,
1539 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
1541 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, m_defaultCreationOptions);
1544 /// <summary>
1545 /// Creates a <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that represents a pair of
1546 /// begin and end methods that conform to the Asynchronous Programming Model pattern.
1547 /// </summary>
1548 /// <typeparam name="TArg1">The type of the first argument passed to the <paramref
1549 /// name="beginMethod"/> delegate.</typeparam>
1550 /// <typeparam name="TArg2">The type of the second argument passed to <paramref name="beginMethod"/>
1551 /// delegate.</typeparam>
1552 /// <typeparam name="TArg3">The type of the third argument passed to <paramref name="beginMethod"/>
1553 /// delegate.</typeparam>
1554 /// <typeparam name="TResult">The type of the result available through the
1555 /// <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.
1556 /// </typeparam>
1557 /// <param name="beginMethod">The delegate that begins the asynchronous operation.</param>
1558 /// <param name="endMethod">The delegate that ends the asynchronous operation.</param>
1559 /// <param name="arg1">The first argument passed to the <paramref name="beginMethod"/>
1560 /// delegate.</param>
1561 /// <param name="arg2">The second argument passed to the <paramref name="beginMethod"/>
1562 /// delegate.</param>
1563 /// <param name="arg3">The third argument passed to the <paramref name="beginMethod"/>
1564 /// delegate.</param>
1565 /// <param name="creationOptions">The TaskCreationOptions value that controls the behavior of the
1566 /// created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
1567 /// <param name="state">An object containing data to be used by the <paramref name="beginMethod"/>
1568 /// delegate.</param>
1569 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1570 /// <paramref name="beginMethod"/> argument is null.</exception>
1571 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1572 /// <paramref name="endMethod"/> argument is null.</exception>
1573 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1574 /// <paramref name="creationOptions"/> argument specifies an invalid TaskCreationOptions
1575 /// value.</exception>
1576 /// <returns>The created <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see> that
1577 /// represents the asynchronous operation.</returns>
1578 /// <remarks>
1579 /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>.
1580 /// </remarks>
1581 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>(
1582 Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod,
1583 Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
1585 return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, creationOptions);
1588 /// <summary>
1589 /// Check validity of options passed to FromAsync method
1590 /// </summary>
1591 /// <param name="creationOptions">The options to be validated.</param>
1592 /// <param name="hasBeginMethod">determines type of FromAsync method that called this method</param>
1593 internal static void CheckFromAsyncOptions(TaskCreationOptions creationOptions, bool hasBeginMethod)
1595 if (hasBeginMethod)
1597 // Options detected here cause exceptions in FromAsync methods that take beginMethod as a parameter
1598 if ((creationOptions & TaskCreationOptions.LongRunning) != 0)
1599 throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_LongRunning"));
1600 if ((creationOptions & TaskCreationOptions.PreferFairness) != 0)
1601 throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_PreferFairness"));
1604 // Check for general validity of options
1605 if ((creationOptions &
1606 ~(TaskCreationOptions.AttachedToParent |
1607 TaskCreationOptions.DenyChildAttach |
1608 TaskCreationOptions.HideScheduler |
1609 TaskCreationOptions.PreferFairness |
1610 TaskCreationOptions.LongRunning)) != 0)
1612 throw new ArgumentOutOfRangeException("creationOptions");
1618 // ContinueWhenAll methods
1621 // A Task<Task[]> that, given an initial collection of N tasks, will complete when
1622 // it has been invoked N times. This allows us to replace this logic:
1623 // Task<Task[]> promise = new Task<Task[]>(...);
1624 // int _count = tasksCopy.Length;
1625 // Action<Task> completionAction = delegate {if(Interlocked.Decrement(ref _count) == 0) promise.TrySetResult(tasksCopy);
1626 // for(int i=0; i<_count; i++)
1627 // tasksCopy[i].AddCompletionAction(completionAction);
1628 // with this logic:
1629 // CompletionOnCountdownPromise promise = new CompletionOnCountdownPromise(tasksCopy);
1630 // for(int i=0; i<tasksCopy.Length; i++) tasksCopy[i].AddCompletionAction(promise);
1631 // which saves a few allocations.
1633 // Used in TaskFactory.CommonCWAllLogic(Task[]), below.
1634 private sealed class CompleteOnCountdownPromise : Task<Task[]>, ITaskCompletionAction
1636 private readonly Task[] _tasks;
1637 private int _count;
1639 internal CompleteOnCountdownPromise(Task[] tasksCopy) : base()
1641 Contract.Requires((tasksCopy != null) && (tasksCopy.Length > 0), "Expected non-null task array with at least one element in it");
1642 _tasks = tasksCopy;
1643 _count = tasksCopy.Length;
1645 if (AsyncCausalityTracer.LoggingOn)
1646 AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAll", 0);
1648 if (Task.s_asyncDebuggingEnabled)
1650 AddToActiveTasks(this);
1654 public void Invoke(Task completingTask)
1656 if (AsyncCausalityTracer.LoggingOn)
1657 AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Join);
1659 if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true);
1660 if (Interlocked.Decrement(ref _count) == 0)
1662 if (AsyncCausalityTracer.LoggingOn)
1663 AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
1665 if (Task.s_asyncDebuggingEnabled)
1667 RemoveFromActiveTasks(this.Id);
1670 TrySetResult(_tasks);
1672 Contract.Assert(_count >= 0, "Count should never go below 0");
1675 /// <summary>
1676 /// Returns whether we should notify the debugger of a wait completion. This returns
1677 /// true iff at least one constituent task has its bit set.
1678 /// </summary>
1679 internal override bool ShouldNotifyDebuggerOfWaitCompletion
1683 return
1684 base.ShouldNotifyDebuggerOfWaitCompletion &&
1685 Task.AnyTaskRequiresNotifyDebuggerOfWaitCompletion(_tasks);
1690 // Performs some logic common to all ContinueWhenAll() overloads
1691 internal static Task<Task[]> CommonCWAllLogic(Task[] tasksCopy)
1693 Contract.Requires(tasksCopy != null);
1695 // Create a promise task to be returned to the user
1696 CompleteOnCountdownPromise promise = new CompleteOnCountdownPromise(tasksCopy);
1698 for (int i = 0; i < tasksCopy.Length; i++)
1700 if (tasksCopy[i].IsCompleted) promise.Invoke(tasksCopy[i]); // Short-circuit the completion action, if possible
1701 else tasksCopy[i].AddCompletionAction(promise); // simple completion action
1704 return promise;
1708 // A Task<Task<T>[]> that, given an initial collection of N tasks, will complete when
1709 // it has been invoked N times. See comments for non-generic CompleteOnCountdownPromise class.
1711 // Used in TaskFactory.CommonCWAllLogic<TResult>(Task<TResult>[]), below.
1712 private sealed class CompleteOnCountdownPromise<T> : Task<Task<T>[]>, ITaskCompletionAction
1714 private readonly Task<T>[] _tasks;
1715 private int _count;
1717 internal CompleteOnCountdownPromise(Task<T>[] tasksCopy) : base()
1719 Contract.Requires((tasksCopy != null) && (tasksCopy.Length > 0), "Expected non-null task array with at least one element in it");
1720 _tasks = tasksCopy;
1721 _count = tasksCopy.Length;
1723 if (AsyncCausalityTracer.LoggingOn)
1724 AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAll<>", 0);
1726 if (Task.s_asyncDebuggingEnabled)
1728 AddToActiveTasks(this);
1732 public void Invoke(Task completingTask)
1734 if (AsyncCausalityTracer.LoggingOn)
1735 AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Join);
1737 if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true);
1738 if (Interlocked.Decrement(ref _count) == 0)
1740 if (AsyncCausalityTracer.LoggingOn)
1741 AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
1743 if (Task.s_asyncDebuggingEnabled)
1745 RemoveFromActiveTasks(this.Id);
1748 TrySetResult(_tasks);
1750 Contract.Assert(_count >= 0, "Count should never go below 0");
1753 /// <summary>
1754 /// Returns whether we should notify the debugger of a wait completion. This returns
1755 /// true iff at least one constituent task has its bit set.
1756 /// </summary>
1757 internal override bool ShouldNotifyDebuggerOfWaitCompletion
1761 return
1762 base.ShouldNotifyDebuggerOfWaitCompletion &&
1763 Task.AnyTaskRequiresNotifyDebuggerOfWaitCompletion(_tasks);
1769 internal static Task<Task<T>[]> CommonCWAllLogic<T>(Task<T>[] tasksCopy)
1771 Contract.Requires(tasksCopy != null);
1773 // Create a promise task to be returned to the user
1774 CompleteOnCountdownPromise<T> promise = new CompleteOnCountdownPromise<T>(tasksCopy);
1776 for (int i = 0; i < tasksCopy.Length; i++)
1778 if (tasksCopy[i].IsCompleted) promise.Invoke(tasksCopy[i]); // Short-circuit the completion action, if possible
1779 else tasksCopy[i].AddCompletionAction(promise); // simple completion action
1782 return promise;
1784 /// <summary>
1785 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1786 /// that will be started upon the completion of a set of provided Tasks.
1787 /// </summary>
1788 /// <param name="tasks">The array of tasks from which to continue.</param>
1789 /// <param name="continuationAction">The action delegate to execute when all tasks in
1790 /// the <paramref name="tasks"/> array have completed.</param>
1791 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1792 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1793 /// <paramref name="tasks"/> array is null.</exception>
1794 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1795 /// <paramref name="continuationAction"/> argument is null.</exception>
1796 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1797 /// <paramref name="tasks"/> array contains a null value.</exception>
1798 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1799 /// <paramref name="tasks"/> array is empty.</exception>
1800 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1801 public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction)
1803 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1804 Contract.EndContractBlock();
1806 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1807 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
1811 /// <summary>
1812 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1813 /// that will be started upon the completion of a set of provided Tasks.
1814 /// </summary>
1815 /// <param name="tasks">The array of tasks from which to continue.</param>
1816 /// <param name="continuationAction">The action delegate to execute when all tasks in
1817 /// the <paramref name="tasks"/> array have completed.</param>
1818 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
1819 /// that will be assigned to the new continuation task.</param>
1820 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1821 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1822 /// <paramref name="tasks"/> array is null.</exception>
1823 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1824 /// <paramref name="continuationAction"/> argument is null.</exception>
1825 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1826 /// <paramref name="tasks"/> array contains a null value.</exception>
1827 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1828 /// <paramref name="tasks"/> array is empty.</exception>
1829 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1830 /// has already been disposed.
1831 /// </exception>
1832 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1833 public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
1835 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1836 Contract.EndContractBlock();
1838 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1839 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
1842 /// <summary>
1843 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1844 /// that will be started upon the completion of a set of provided Tasks.
1845 /// </summary>
1846 /// <param name="tasks">The array of tasks from which to continue.</param>
1847 /// <param name="continuationAction">The action delegate to execute when all tasks in the <paramref
1848 /// name="tasks"/> array have completed.</param>
1849 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
1850 /// TaskContinuationOptions</see> value that controls the behavior of
1851 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1852 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1853 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1854 /// <paramref name="tasks"/> array is null.</exception>
1855 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1856 /// <paramref name="continuationAction"/> argument is null.</exception>
1857 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1858 /// <paramref name="tasks"/> array contains a null value.</exception>
1859 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1860 /// <paramref name="tasks"/> array is empty.</exception>
1861 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1862 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
1863 /// value.</exception>
1864 /// <remarks>
1865 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
1866 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
1867 /// will be executed, are illegal with ContinueWhenAll.
1868 /// </remarks>
1869 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1870 public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, TaskContinuationOptions continuationOptions)
1872 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1873 Contract.EndContractBlock();
1875 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1876 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
1879 /// <summary>
1880 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1881 /// that will be started upon the completion of a set of provided Tasks.
1882 /// </summary>
1883 /// <param name="tasks">The array of tasks from which to continue.</param>
1884 /// <param name="continuationAction">The action delegate to execute when all tasks in the <paramref
1885 /// name="tasks"/> array have completed.</param>
1886 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
1887 /// that will be assigned to the new continuation task.</param>
1888 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
1889 /// TaskContinuationOptions</see> value that controls the behavior of
1890 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1891 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
1892 /// that is used to schedule the created continuation <see
1893 /// cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1894 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1895 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1896 /// <paramref name="tasks"/> array is null.</exception>
1897 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1898 /// <paramref name="continuationAction"/> argument is null.</exception>
1899 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1900 /// <paramref name="scheduler"/> argument is null.</exception>
1901 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1902 /// <paramref name="tasks"/> array contains a null value.</exception>
1903 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1904 /// <paramref name="tasks"/> array is empty.</exception>
1905 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
1906 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
1907 /// value.</exception>
1908 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1909 /// has already been disposed.
1910 /// </exception>
1911 /// <remarks>
1912 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
1913 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
1914 /// will be executed, are illegal with ContinueWhenAll.
1915 /// </remarks>
1916 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1917 public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
1918 TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
1920 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1921 Contract.EndContractBlock();
1923 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1924 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
1927 /// <summary>
1928 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1929 /// that will be started upon the completion of a set of provided Tasks.
1930 /// </summary>
1931 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
1932 /// <param name="tasks">The array of tasks from which to continue.</param>
1933 /// <param name="continuationAction">The action delegate to execute when all tasks in
1934 /// the <paramref name="tasks"/> array have completed.</param>
1935 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1936 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1937 /// <paramref name="tasks"/> array is null.</exception>
1938 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1939 /// <paramref name="continuationAction"/> argument is null.</exception>
1940 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1941 /// <paramref name="tasks"/> array contains a null value.</exception>
1942 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1943 /// <paramref name="tasks"/> array is empty.</exception>
1944 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1945 public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction)
1947 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1948 Contract.EndContractBlock();
1950 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1951 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
1955 /// <summary>
1956 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1957 /// that will be started upon the completion of a set of provided Tasks.
1958 /// </summary>
1959 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
1960 /// <param name="tasks">The array of tasks from which to continue.</param>
1961 /// <param name="continuationAction">The action delegate to execute when all tasks in
1962 /// the <paramref name="tasks"/> array have completed.</param>
1963 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
1964 /// that will be assigned to the new continuation task.</param>
1965 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
1966 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1967 /// <paramref name="tasks"/> array is null.</exception>
1968 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
1969 /// <paramref name="continuationAction"/> argument is null.</exception>
1970 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1971 /// <paramref name="tasks"/> array contains a null value.</exception>
1972 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
1973 /// <paramref name="tasks"/> array is empty.</exception>
1974 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
1975 /// has already been disposed.
1976 /// </exception>
1977 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
1978 public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
1979 CancellationToken cancellationToken)
1981 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
1982 Contract.EndContractBlock();
1984 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
1985 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
1988 /// <summary>
1989 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
1990 /// that will be started upon the completion of a set of provided Tasks.
1991 /// </summary>
1992 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
1993 /// <param name="tasks">The array of tasks from which to continue.</param>
1994 /// <param name="continuationAction">The action delegate to execute when all tasks in the <paramref
1995 /// name="tasks"/> array have completed.</param>
1996 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
1997 /// TaskContinuationOptions</see> value that controls the behavior of
1998 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
1999 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2000 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2001 /// <paramref name="tasks"/> array is null.</exception>
2002 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2003 /// <paramref name="continuationAction"/> argument is null.</exception>
2004 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2005 /// <paramref name="tasks"/> array contains a null value.</exception>
2006 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2007 /// <paramref name="tasks"/> array is empty.</exception>
2008 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2009 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2010 /// value.</exception>
2011 /// <remarks>
2012 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2013 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2014 /// will be executed, are illegal with ContinueWhenAll.
2015 /// </remarks>
2016 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2017 public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
2018 TaskContinuationOptions continuationOptions)
2020 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2021 Contract.EndContractBlock();
2023 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2024 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2027 /// <summary>
2028 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2029 /// that will be started upon the completion of a set of provided Tasks.
2030 /// </summary>
2031 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2032 /// <param name="tasks">The array of tasks from which to continue.</param>
2033 /// <param name="continuationAction">The action delegate to execute when all tasks in the <paramref
2034 /// name="tasks"/> array have completed.</param>
2035 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2036 /// that will be assigned to the new continuation task.</param>
2037 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2038 /// TaskContinuationOptions</see> value that controls the behavior of
2039 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
2040 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2041 /// that is used to schedule the created continuation <see
2042 /// cref="T:System.Threading.Tasks.Task">Task</see>.</param>
2043 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2044 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2045 /// <paramref name="tasks"/> array is null.</exception>
2046 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2047 /// <paramref name="continuationAction"/> argument is null.</exception>
2048 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2049 /// <paramref name="scheduler"/> argument is null.</exception>
2050 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2051 /// <paramref name="tasks"/> array contains a null value.</exception>
2052 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2053 /// <paramref name="tasks"/> array is empty.</exception>
2054 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2055 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2056 /// value.</exception>
2057 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2058 /// has already been disposed.
2059 /// </exception>
2060 /// <remarks>
2061 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2062 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2063 /// will be executed, are illegal with ContinueWhenAll.
2064 /// </remarks>
2065 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2066 public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
2067 CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2069 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2070 Contract.EndContractBlock();
2072 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2073 return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
2076 /// <summary>
2077 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2078 /// that will be started upon the completion of a set of provided Tasks.
2079 /// </summary>
2080 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2081 /// name="continuationFunction"/>
2082 /// delegate and associated with the created <see
2083 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2084 /// <param name="tasks">The array of tasks from which to continue.</param>
2085 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2086 /// <paramref name="tasks"/> array have completed.</param>
2087 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2088 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2089 /// <paramref name="tasks"/> array is null.</exception>
2090 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2091 /// <paramref name="continuationFunction"/> argument is null.</exception>
2092 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2093 /// <paramref name="tasks"/> array contains a null value.</exception>
2094 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2095 /// <paramref name="tasks"/> array is empty.</exception>
2096 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2097 public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction)
2099 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2100 Contract.EndContractBlock();
2102 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2103 return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2107 /// <summary>
2108 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2109 /// that will be started upon the completion of a set of provided Tasks.
2110 /// </summary>
2111 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2112 /// name="continuationFunction"/>
2113 /// delegate and associated with the created <see
2114 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2115 /// <param name="tasks">The array of tasks from which to continue.</param>
2116 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2117 /// <paramref name="tasks"/> array have completed.</param>
2118 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2119 /// that will be assigned to the new continuation task.</param>
2120 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2121 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2122 /// <paramref name="tasks"/> array is null.</exception>
2123 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2124 /// <paramref name="continuationFunction"/> argument is null.</exception>
2125 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2126 /// <paramref name="tasks"/> array contains a null value.</exception>
2127 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2128 /// <paramref name="tasks"/> array is empty.</exception>
2129 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2130 /// has already been disposed.
2131 /// </exception>
2132 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2133 public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken)
2135 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2136 Contract.EndContractBlock();
2138 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2139 return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
2142 /// <summary>
2143 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2144 /// that will be started upon the completion of a set of provided Tasks.
2145 /// </summary>
2146 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2147 /// name="continuationFunction"/>
2148 /// delegate and associated with the created <see
2149 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2150 /// <param name="tasks">The array of tasks from which to continue.</param>
2151 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2152 /// <paramref name="tasks"/> array have completed.</param>
2153 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2154 /// TaskContinuationOptions</see> value that controls the behavior of
2155 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2156 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2157 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2158 /// <paramref name="tasks"/> array is null.</exception>
2159 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2160 /// <paramref name="continuationFunction"/> argument is null.</exception>
2161 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2162 /// <paramref name="tasks"/> array contains a null value.</exception>
2163 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2164 /// <paramref name="tasks"/> array is empty.</exception>
2165 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2166 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2167 /// value.</exception>
2168 /// <remarks>
2169 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2170 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2171 /// will be executed, are illegal with ContinueWhenAll.
2172 /// </remarks>
2173 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2174 public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, TaskContinuationOptions continuationOptions)
2176 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2177 Contract.EndContractBlock();
2179 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2180 return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2183 /// <summary>
2184 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2185 /// that will be started upon the completion of a set of provided Tasks.
2186 /// </summary>
2187 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2188 /// name="continuationFunction"/>
2189 /// delegate and associated with the created <see
2190 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2191 /// <param name="tasks">The array of tasks from which to continue.</param>
2192 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2193 /// <paramref name="tasks"/> array have completed.</param>
2194 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2195 /// that will be assigned to the new continuation task.</param>
2196 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2197 /// TaskContinuationOptions</see> value that controls the behavior of
2198 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2199 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2200 /// that is used to schedule the created continuation <see
2201 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
2202 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2203 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2204 /// <paramref name="tasks"/> array is null.</exception>
2205 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2206 /// <paramref name="continuationFunction"/> argument is null.</exception>
2207 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2208 /// <paramref name="scheduler"/> argument is null.</exception>
2209 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2210 /// <paramref name="tasks"/> array contains a null value.</exception>
2211 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2212 /// <paramref name="tasks"/> array is empty.</exception>
2213 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2214 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2215 /// value.</exception>
2216 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2217 /// has already been disposed.
2218 /// </exception>
2219 /// <remarks>
2220 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2221 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2222 /// will be executed, are illegal with ContinueWhenAll.
2223 /// </remarks>
2224 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2225 public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken,
2226 TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2228 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2229 Contract.EndContractBlock();
2231 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2232 return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
2236 /// <summary>
2237 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2238 /// that will be started upon the completion of a set of provided Tasks.
2239 /// </summary>
2240 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2241 /// name="continuationFunction"/>
2242 /// delegate and associated with the created <see
2243 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2244 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2245 /// <param name="tasks">The array of tasks from which to continue.</param>
2246 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2247 /// <paramref name="tasks"/> array have completed.</param>
2248 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2249 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2250 /// <paramref name="tasks"/> array is null.</exception>
2251 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2252 /// <paramref name="continuationFunction"/> argument is null.</exception>
2253 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2254 /// <paramref name="tasks"/> array contains a null value.</exception>
2255 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2256 /// <paramref name="tasks"/> array is empty.</exception>
2257 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2258 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction)
2260 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2261 Contract.EndContractBlock();
2263 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2264 return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2267 /// <summary>
2268 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2269 /// that will be started upon the completion of a set of provided Tasks.
2270 /// </summary>
2271 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2272 /// name="continuationFunction"/>
2273 /// delegate and associated with the created <see
2274 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2275 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2276 /// <param name="tasks">The array of tasks from which to continue.</param>
2277 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2278 /// <paramref name="tasks"/> array have completed.</param>
2279 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2280 /// that will be assigned to the new continuation task.</param>
2281 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2282 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2283 /// <paramref name="tasks"/> array is null.</exception>
2284 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2285 /// <paramref name="continuationFunction"/> argument is null.</exception>
2286 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2287 /// <paramref name="tasks"/> array contains a null value.</exception>
2288 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2289 /// <paramref name="tasks"/> array is empty.</exception>
2290 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2291 /// has already been disposed.
2292 /// </exception>
2293 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2294 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
2295 CancellationToken cancellationToken)
2297 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2298 Contract.EndContractBlock();
2300 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2301 return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
2304 /// <summary>
2305 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2306 /// that will be started upon the completion of a set of provided Tasks.
2307 /// </summary>
2308 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2309 /// name="continuationFunction"/>
2310 /// delegate and associated with the created <see
2311 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2312 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2313 /// <param name="tasks">The array of tasks from which to continue.</param>
2314 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2315 /// <paramref name="tasks"/> array have completed.</param>
2316 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2317 /// TaskContinuationOptions</see> value that controls the behavior of
2318 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2319 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2320 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2321 /// <paramref name="tasks"/> array is null.</exception>
2322 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2323 /// <paramref name="continuationFunction"/> argument is null.</exception>
2324 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2325 /// <paramref name="tasks"/> array contains a null value.</exception>
2326 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2327 /// <paramref name="tasks"/> array is empty.</exception>
2328 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2329 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2330 /// value.</exception>
2331 /// <remarks>
2332 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2333 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2334 /// will be executed, are illegal with ContinueWhenAll.
2335 /// </remarks>
2336 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2337 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
2338 TaskContinuationOptions continuationOptions)
2340 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2341 Contract.EndContractBlock();
2343 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2344 return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2347 /// <summary>
2348 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2349 /// that will be started upon the completion of a set of provided Tasks.
2350 /// </summary>
2351 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2352 /// name="continuationFunction"/>
2353 /// delegate and associated with the created <see
2354 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2355 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2356 /// <param name="tasks">The array of tasks from which to continue.</param>
2357 /// <param name="continuationFunction">The function delegate to execute when all tasks in the
2358 /// <paramref name="tasks"/> array have completed.</param>
2359 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2360 /// that will be assigned to the new continuation task.</param>
2361 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2362 /// TaskContinuationOptions</see> value that controls the behavior of
2363 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2364 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2365 /// that is used to schedule the created continuation <see
2366 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
2367 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2368 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2369 /// <paramref name="tasks"/> array is null.</exception>
2370 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2371 /// <paramref name="continuationFunction"/> argument is null.</exception>
2372 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2373 /// <paramref name="scheduler"/> argument is null.</exception>
2374 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2375 /// <paramref name="tasks"/> array contains a null value.</exception>
2376 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2377 /// <paramref name="tasks"/> array is empty.</exception>
2378 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2379 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2380 /// value.</exception>
2381 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2382 /// has already been disposed.
2383 /// </exception>
2384 /// <remarks>
2385 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2386 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2387 /// will be executed, are illegal with ContinueWhenAll.
2388 /// </remarks>
2389 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2390 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
2391 CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2393 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2394 Contract.EndContractBlock();
2396 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2397 return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
2401 // ContinueWhenAny methods
2404 // A Task<Task> that will be completed the first time that Invoke is called.
2405 // It allows us to replace this logic:
2406 // Task<Task> promise = new Task<Task>(...);
2407 // Action<Task> completionAction = delegate(Task completingTask) { promise.TrySetResult(completingTask); }
2408 // for(int i=0; i<tasksCopy.Length; i++) tasksCopy[i].AddCompletionAction(completionAction);
2409 // with this logic:
2410 // CompletionOnInvokePromise promise = new CompletionOnInvokePromise(tasksCopy);
2411 // for(int i=0; i<tasksCopy.Length; i++) tasksCopy[i].AddCompletionAction(promise);
2412 // which saves a couple of allocations.
2414 // Used in TaskFactory.CommonCWAnyLogic(), below.
2415 internal sealed class CompleteOnInvokePromise : Task<Task>, ITaskCompletionAction
2417 private IList<Task> _tasks; // must track this for cleanup
2418 private int m_firstTaskAlreadyCompleted;
2420 public CompleteOnInvokePromise(IList<Task> tasks) : base()
2422 Contract.Requires(tasks != null, "Expected non-null collection of tasks");
2423 _tasks = tasks;
2425 if (AsyncCausalityTracer.LoggingOn)
2426 AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAny", 0);
2428 if (Task.s_asyncDebuggingEnabled)
2430 AddToActiveTasks(this);
2434 public void Invoke(Task completingTask)
2436 if (Interlocked.CompareExchange(ref m_firstTaskAlreadyCompleted, 1, 0) == 0)
2438 if (AsyncCausalityTracer.LoggingOn)
2440 AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Choice);
2441 AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
2444 if (Task.s_asyncDebuggingEnabled)
2446 RemoveFromActiveTasks(this.Id);
2449 bool success = TrySetResult(completingTask);
2450 Contract.Assert(success, "Only one task should have gotten to this point, and thus this must be successful.");
2452 // We need to remove continuations that may be left straggling on other tasks.
2453 // Otherwise, repeated calls to WhenAny using the same task could leak actions.
2454 // This may also help to avoided unnecessary invocations of this whenComplete delegate.
2455 // Note that we may be attempting to remove a continuation from a task that hasn't had it
2456 // added yet; while there's overhead there, the operation won't hurt anything.
2457 var tasks = _tasks;
2458 int numTasks = tasks.Count;
2459 for (int i = 0; i < numTasks; i++)
2461 var task = tasks[i];
2462 if (task != null && // if an element was erroneously nulled out concurrently, just skip it; worst case is we don't remove a continuation
2463 !task.IsCompleted) task.RemoveContinuation(this);
2465 _tasks = null;
2470 // Common ContinueWhenAny logic
2471 // If the tasks list is not an array, it must be an internal defensive copy so that
2472 // we don't need to be concerned about concurrent modifications to the list. If the task list
2473 // is an array, it should be a defensive copy if this functionality is being used
2474 // asynchronously (e.g. WhenAny) rather than synchronously (e.g. WaitAny).
2475 internal static Task<Task> CommonCWAnyLogic(IList<Task> tasks)
2477 Contract.Requires(tasks != null);
2479 // Create a promise task to be returned to the user
2480 var promise = new CompleteOnInvokePromise(tasks);
2482 // At the completion of any of the tasks, complete the promise.
2484 bool checkArgsOnly = false;
2485 int numTasks = tasks.Count;
2486 for(int i=0; i<numTasks; i++)
2488 var task = tasks[i];
2489 if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
2491 if (checkArgsOnly) continue;
2493 // If the promise has already completed, don't bother with checking any more tasks.
2494 if (promise.IsCompleted)
2496 checkArgsOnly = true;
2498 // If a task has already completed, complete the promise.
2499 else if (task.IsCompleted)
2501 promise.Invoke(task);
2502 checkArgsOnly = true;
2504 // Otherwise, add the completion action and keep going.
2505 else
2507 task.AddCompletionAction(promise);
2508 if (promise.IsCompleted)
2510 // One of the previous tasks that already had its continuation registered may have
2511 // raced to complete with our adding the continuation to this task. The completion
2512 // routine would have gone through and removed the continuation from all of the tasks
2513 // with which it was already registered, but if the ---- causes this continuation to
2514 // be added after that, it'll never be removed. As such, after adding the continuation,
2515 // we check to see whether the promise has already completed, and if it has, we try to
2516 // manually remove the continuation from this task. If it was already removed, it'll be
2517 // a nop, and if we ---- to remove it, the synchronization in RemoveContinuation will
2518 // keep things consistent.
2519 task.RemoveContinuation(promise);
2524 return promise;
2528 /// <summary>
2529 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2530 /// that will be started upon the completion of any Task in the provided set.
2531 /// </summary>
2532 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2533 /// <param name="continuationAction">The action delegate to execute when one task in the <paramref
2534 /// name="tasks"/> array completes.</param>
2535 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2536 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2537 /// <paramref name="tasks"/> array is null.</exception>
2538 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2539 /// <paramref name="continuationAction"/> argument is null.</exception>
2540 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2541 /// <paramref name="tasks"/> array contains a null value.</exception>
2542 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2543 /// <paramref name="tasks"/> array is empty.</exception>
2544 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2545 public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction)
2547 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2548 Contract.EndContractBlock();
2550 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2551 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2554 /// <summary>
2555 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2556 /// that will be started upon the completion of any Task in the provided set.
2557 /// </summary>
2558 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2559 /// <param name="continuationAction">The action delegate to execute when one task in the <paramref
2560 /// name="tasks"/> array completes.</param>
2561 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2562 /// that will be assigned to the new continuation task.</param>
2563 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2564 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2565 /// <paramref name="tasks"/> array is null.</exception>
2566 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2567 /// <paramref name="continuationAction"/> argument is null.</exception>
2568 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2569 /// <paramref name="tasks"/> array contains a null value.</exception>
2570 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2571 /// <paramref name="tasks"/> array is empty.</exception>
2572 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2573 /// has already been disposed.
2574 /// </exception>
2575 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2576 public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
2578 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2579 Contract.EndContractBlock();
2581 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2582 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
2585 /// <summary>
2586 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2587 /// that will be started upon the completion of any Task in the provided set.
2588 /// </summary>
2589 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2590 /// <param name="continuationAction">The action delegate to execute when one task in the <paramref
2591 /// name="tasks"/> array completes.</param>
2592 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2593 /// TaskContinuationOptions</see> value that controls the behavior of
2594 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
2595 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2596 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2597 /// <paramref name="tasks"/> array is null.</exception>
2598 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2599 /// <paramref name="continuationAction"/> argument is null.</exception>
2600 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2601 /// <paramref name="tasks"/> array contains a null value.</exception>
2602 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2603 /// <paramref name="tasks"/> array is empty.</exception>
2604 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2605 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2606 /// value.</exception>
2607 /// <remarks>
2608 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2609 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2610 /// will be executed, are illegal with ContinueWhenAny.
2611 /// </remarks>
2612 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2613 public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
2615 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2616 Contract.EndContractBlock();
2618 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2619 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2622 /// <summary>
2623 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2624 /// that will be started upon the completion of any Task in the provided set.
2625 /// </summary>
2626 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2627 /// <param name="continuationAction">The action delegate to execute when one task in the <paramref
2628 /// name="tasks"/> array completes.</param>
2629 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2630 /// that will be assigned to the new continuation task.</param>
2631 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2632 /// TaskContinuationOptions</see> value that controls the behavior of
2633 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
2634 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2635 /// that is used to schedule the created continuation <see
2636 /// cref="T:System.Threading.Tasks.Task">Task</see>.</param>
2637 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</returns>
2638 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2639 /// <paramref name="tasks"/> array is null.</exception>
2640 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2641 /// <paramref name="continuationAction"/> argument is null.</exception>
2642 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2643 /// <paramref name="scheduler"/> argument is null.</exception>
2644 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2645 /// <paramref name="tasks"/> array contains a null value.</exception>
2646 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2647 /// <paramref name="tasks"/> array is empty.</exception>
2648 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2649 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2650 /// value.</exception>
2651 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2652 /// has already been disposed.
2653 /// </exception>
2654 /// <remarks>
2655 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2656 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2657 /// will be executed, are illegal with ContinueWhenAny.
2658 /// </remarks>
2659 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2660 public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken,
2661 TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2663 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
2664 Contract.EndContractBlock();
2666 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2667 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
2671 /// <summary>
2672 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2673 /// that will be started upon the completion of any Task in the provided set.
2674 /// </summary>
2675 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2676 /// name="continuationFunction"/>
2677 /// delegate and associated with the created <see
2678 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2679 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2680 /// <param name="continuationFunction">The function delegate to execute when one task in the
2681 /// <paramref name="tasks"/> array completes.</param>
2682 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2683 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2684 /// <paramref name="tasks"/> array is null.</exception>
2685 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2686 /// <paramref name="continuationFunction"/> argument is null.</exception>
2687 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2688 /// <paramref name="tasks"/> array contains a null value.</exception>
2689 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2690 /// <paramref name="tasks"/> array is empty.</exception>
2691 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2692 public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction)
2694 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2695 Contract.EndContractBlock();
2697 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2698 return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2701 /// <summary>
2702 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2703 /// that will be started upon the completion of any Task in the provided set.
2704 /// </summary>
2705 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2706 /// name="continuationFunction"/>
2707 /// delegate and associated with the created <see
2708 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2709 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2710 /// <param name="continuationFunction">The function delegate to execute when one task in the
2711 /// <paramref name="tasks"/> array completes.</param>
2712 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2713 /// that will be assigned to the new continuation task.</param>
2714 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2715 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2716 /// <paramref name="tasks"/> array is null.</exception>
2717 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2718 /// <paramref name="continuationFunction"/> argument is null.</exception>
2719 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2720 /// <paramref name="tasks"/> array contains a null value.</exception>
2721 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2722 /// <paramref name="tasks"/> array is empty.</exception>
2723 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2724 /// has already been disposed.
2725 /// </exception>
2726 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2727 public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken)
2729 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2730 Contract.EndContractBlock();
2732 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2733 return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
2736 /// <summary>
2737 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2738 /// that will be started upon the completion of any Task in the provided set.
2739 /// </summary>
2740 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2741 /// name="continuationFunction"/>
2742 /// delegate and associated with the created <see
2743 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2744 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2745 /// <param name="continuationFunction">The function delegate to execute when one task in the
2746 /// <paramref name="tasks"/> array completes.</param>
2747 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2748 /// TaskContinuationOptions</see> value that controls the behavior of
2749 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2750 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2751 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2752 /// <paramref name="tasks"/> array is null.</exception>
2753 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2754 /// <paramref name="continuationFunction"/> argument is null.</exception>
2755 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2756 /// <paramref name="tasks"/> array contains a null value.</exception>
2757 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2758 /// <paramref name="tasks"/> array is empty.</exception>
2759 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2760 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2761 /// value.</exception>
2762 /// <remarks>
2763 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2764 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2765 /// will be executed, are illegal with ContinueWhenAny.
2766 /// </remarks>
2767 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2768 public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions)
2770 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2771 Contract.EndContractBlock();
2773 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2774 return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null,continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2777 /// <summary>
2778 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2779 /// that will be started upon the completion of any Task in the provided set.
2780 /// </summary>
2781 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2782 /// name="continuationFunction"/>
2783 /// delegate and associated with the created <see
2784 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2785 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2786 /// <param name="continuationFunction">The function delegate to execute when one task in the
2787 /// <paramref name="tasks"/> array completes.</param>
2788 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2789 /// that will be assigned to the new continuation task.</param>
2790 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2791 /// TaskContinuationOptions</see> value that controls the behavior of
2792 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2793 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2794 /// that is used to schedule the created continuation <see
2795 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
2796 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2797 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2798 /// <paramref name="tasks"/> array is null.</exception>
2799 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2800 /// <paramref name="continuationFunction"/> argument is null.</exception>
2801 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2802 /// <paramref name="scheduler"/> argument is null.</exception>
2803 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2804 /// <paramref name="tasks"/> array contains a null value.</exception>
2805 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2806 /// <paramref name="tasks"/> array is empty.</exception>
2807 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2808 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2809 /// value.</exception>
2810 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2811 /// has already been disposed.
2812 /// </exception>
2813 /// <remarks>
2814 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2815 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2816 /// will be executed, are illegal with ContinueWhenAny.
2817 /// </remarks>
2818 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2819 public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken,
2820 TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2822 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2823 Contract.EndContractBlock();
2825 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2826 return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
2829 /// <summary>
2830 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2831 /// that will be started upon the completion of any Task in the provided set.
2832 /// </summary>
2833 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2834 /// name="continuationFunction"/>
2835 /// delegate and associated with the created <see
2836 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2837 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2838 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2839 /// <param name="continuationFunction">The function delegate to execute when one task in the
2840 /// <paramref name="tasks"/> array completes.</param>
2841 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2842 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2843 /// <paramref name="tasks"/> array is null.</exception>
2844 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2845 /// <paramref name="continuationFunction"/> argument is null.</exception>
2846 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2847 /// <paramref name="tasks"/> array contains a null value.</exception>
2848 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2849 /// <paramref name="tasks"/> array is empty.</exception>
2850 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2851 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction)
2853 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2854 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2855 return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2858 /// <summary>
2859 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2860 /// that will be started upon the completion of any Task in the provided set.
2861 /// </summary>
2862 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2863 /// name="continuationFunction"/>
2864 /// delegate and associated with the created <see
2865 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2866 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2867 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2868 /// <param name="continuationFunction">The function delegate to execute when one task in the
2869 /// <paramref name="tasks"/> array completes.</param>
2870 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2871 /// that will be assigned to the new continuation task.</param>
2872 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2873 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2874 /// <paramref name="tasks"/> array is null.</exception>
2875 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2876 /// <paramref name="continuationFunction"/> argument is null.</exception>
2877 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2878 /// <paramref name="tasks"/> array contains a null value.</exception>
2879 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2880 /// <paramref name="tasks"/> array is empty.</exception>
2881 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2882 /// has already been disposed.
2883 /// </exception>
2884 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2885 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
2886 CancellationToken cancellationToken)
2888 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2889 Contract.EndContractBlock();
2891 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2892 return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
2895 /// <summary>
2896 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2897 /// that will be started upon the completion of any Task in the provided set.
2898 /// </summary>
2899 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2900 /// name="continuationFunction"/>
2901 /// delegate and associated with the created <see
2902 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2903 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2904 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2905 /// <param name="continuationFunction">The function delegate to execute when one task in the
2906 /// <paramref name="tasks"/> array completes.</param>
2907 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2908 /// TaskContinuationOptions</see> value that controls the behavior of
2909 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2910 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2911 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2912 /// <paramref name="tasks"/> array is null.</exception>
2913 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2914 /// <paramref name="continuationFunction"/> argument is null.</exception>
2915 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2916 /// <paramref name="tasks"/> array contains a null value.</exception>
2917 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2918 /// <paramref name="tasks"/> array is empty.</exception>
2919 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2920 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2921 /// value.</exception>
2922 /// <remarks>
2923 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2924 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2925 /// will be executed, are illegal with ContinueWhenAny.
2926 /// </remarks>
2927 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2928 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
2929 TaskContinuationOptions continuationOptions)
2931 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2932 Contract.EndContractBlock();
2934 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2935 return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
2938 /// <summary>
2939 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>
2940 /// that will be started upon the completion of any Task in the provided set.
2941 /// </summary>
2942 /// <typeparam name="TResult">The type of the result that is returned by the <paramref
2943 /// name="continuationFunction"/>
2944 /// delegate and associated with the created <see
2945 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</typeparam>
2946 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2947 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2948 /// <param name="continuationFunction">The function delegate to execute when one task in the
2949 /// <paramref name="tasks"/> array completes.</param>
2950 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
2951 /// that will be assigned to the new continuation task.</param>
2952 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
2953 /// TaskContinuationOptions</see> value that controls the behavior of
2954 /// the created continuation <see cref="T:System.Threading.Tasks.Task{TResult}">Task</see>.</param>
2955 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
2956 /// that is used to schedule the created continuation <see
2957 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
2958 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task{TResult}"/>.</returns>
2959 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2960 /// <paramref name="tasks"/> array is null.</exception>
2961 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2962 /// <paramref name="continuationFunction"/> argument is null.</exception>
2963 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
2964 /// <paramref name="scheduler"/> argument is null.</exception>
2965 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2966 /// <paramref name="tasks"/> array contains a null value.</exception>
2967 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
2968 /// <paramref name="tasks"/> array is empty.</exception>
2969 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
2970 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
2971 /// value.</exception>
2972 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
2973 /// has already been disposed.
2974 /// </exception>
2975 /// <remarks>
2976 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
2977 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
2978 /// will be executed, are illegal with ContinueWhenAny.
2979 /// </remarks>
2980 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
2981 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
2982 CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
2984 if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
2985 Contract.EndContractBlock();
2987 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
2988 return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
2992 /// <summary>
2993 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
2994 /// that will be started upon the completion of any Task in the provided set.
2995 /// </summary>
2996 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
2997 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
2998 /// <param name="continuationAction">The action delegate to execute when one task in the
2999 /// <paramref name="tasks"/> array completes.</param>
3000 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task"/>.</returns>
3001 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3002 /// <paramref name="tasks"/> array is null.</exception>
3003 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3004 /// <paramref name="continuationAction"/> argument is null.</exception>
3005 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3006 /// <paramref name="tasks"/> array contains a null value.</exception>
3007 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3008 /// <paramref name="tasks"/> array is empty.</exception>
3009 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
3010 public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction)
3012 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
3013 Contract.EndContractBlock();
3015 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
3016 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
3019 /// <summary>
3020 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
3021 /// that will be started upon the completion of any Task in the provided set.
3022 /// </summary>
3023 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
3024 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
3025 /// <param name="continuationAction">The action delegate to execute when one task in the
3026 /// <paramref name="tasks"/> array completes.</param>
3027 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
3028 /// that will be assigned to the new continuation task.</param>
3029 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task"/>.</returns>
3030 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3031 /// <paramref name="tasks"/> array is null.</exception>
3032 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3033 /// <paramref name="continuationAction"/> argument is null.</exception>
3034 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3035 /// <paramref name="tasks"/> array contains a null value.</exception>
3036 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3037 /// <paramref name="tasks"/> array is empty.</exception>
3038 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
3039 /// has already been disposed.
3040 /// </exception>
3041 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
3042 public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
3043 CancellationToken cancellationToken)
3045 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
3046 Contract.EndContractBlock();
3048 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
3049 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
3052 /// <summary>
3053 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
3054 /// that will be started upon the completion of any Task in the provided set.
3055 /// </summary>
3056 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
3057 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
3058 /// <param name="continuationAction">The action delegate to execute when one task in the
3059 /// <paramref name="tasks"/> array completes.</param>
3060 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
3061 /// TaskContinuationOptions</see> value that controls the behavior of
3062 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
3063 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task"/>.</returns>
3064 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3065 /// <paramref name="tasks"/> array is null.</exception>
3066 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3067 /// <paramref name="continuationAction"/> argument is null.</exception>
3068 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3069 /// <paramref name="tasks"/> array contains a null value.</exception>
3070 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3071 /// <paramref name="tasks"/> array is empty.</exception>
3072 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
3073 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
3074 /// value.</exception>
3075 /// <remarks>
3076 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
3077 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
3078 /// will be executed, are illegal with ContinueWhenAny.
3079 /// </remarks>
3080 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
3081 public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
3082 TaskContinuationOptions continuationOptions)
3084 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
3085 Contract.EndContractBlock();
3087 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
3088 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
3091 /// <summary>
3092 /// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
3093 /// that will be started upon the completion of any Task in the provided set.
3094 /// </summary>
3095 /// <typeparam name="TAntecedentResult">The type of the result of the antecedent <paramref name="tasks"/>.</typeparam>
3096 /// <param name="tasks">The array of tasks from which to continue when one task completes.</param>
3097 /// <param name="continuationAction">The action delegate to execute when one task in the
3098 /// <paramref name="tasks"/> array completes.</param>
3099 /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken">CancellationToken</see>
3100 /// that will be assigned to the new continuation task.</param>
3101 /// <param name="continuationOptions">The <see cref="System.Threading.Tasks.TaskContinuationOptions">
3102 /// TaskContinuationOptions</see> value that controls the behavior of
3103 /// the created continuation <see cref="T:System.Threading.Tasks.Task">Task</see>.</param>
3104 /// <param name="scheduler">The <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see>
3105 /// that is used to schedule the created continuation <see
3106 /// cref="T:System.Threading.Tasks.Task{TResult}"/>.</param>
3107 /// <returns>The new continuation <see cref="T:System.Threading.Tasks.Task"/>.</returns>
3108 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3109 /// <paramref name="tasks"/> array is null.</exception>
3110 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3111 /// <paramref name="continuationAction"/> argument is null.</exception>
3112 /// <exception cref="T:System.ArgumentNullException">The exception that is thrown when the
3113 /// <paramref name="scheduler"/> argument is null.</exception>
3114 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3115 /// <paramref name="tasks"/> array contains a null value.</exception>
3116 /// <exception cref="T:System.ArgumentException">The exception that is thrown when the
3117 /// <paramref name="tasks"/> array is empty.</exception>
3118 /// <exception cref="T:System.ArgumentOutOfRangeException">The exception that is thrown when the
3119 /// <paramref name="continuationOptions"/> argument specifies an invalid TaskContinuationOptions
3120 /// value.</exception>
3121 /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
3122 /// has already been disposed.
3123 /// </exception>
3124 /// <remarks>
3125 /// The NotOn* and OnlyOn* <see cref="System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>,
3126 /// which constrain for which <see cref="System.Threading.Tasks.TaskStatus">TaskStatus</see> states a continuation
3127 /// will be executed, are illegal with ContinueWhenAny.
3128 /// </remarks>
3129 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
3130 public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
3131 CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
3133 if (continuationAction == null) throw new ArgumentNullException("continuationAction");
3134 Contract.EndContractBlock();
3136 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
3137 return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
3140 // Check task array and return a defensive copy.
3141 // Used with ContinueWhenAll()/ContinueWhenAny().
3142 internal static Task[] CheckMultiContinuationTasksAndCopy(Task[] tasks)
3144 if (tasks == null)
3145 throw new ArgumentNullException("tasks");
3146 if (tasks.Length == 0)
3147 throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
3148 Contract.EndContractBlock();
3150 Task[] tasksCopy = new Task[tasks.Length];
3151 for (int i = 0; i < tasks.Length; i++)
3153 tasksCopy[i] = tasks[i];
3155 if (tasksCopy[i] == null)
3156 throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
3159 return tasksCopy;
3162 internal static Task<TResult>[] CheckMultiContinuationTasksAndCopy<TResult>(Task<TResult>[] tasks)
3164 if (tasks == null)
3165 throw new ArgumentNullException("tasks");
3166 if (tasks.Length == 0)
3167 throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
3168 Contract.EndContractBlock();
3170 Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length];
3171 for (int i = 0; i < tasks.Length; i++)
3173 tasksCopy[i] = tasks[i];
3175 if (tasksCopy[i] == null)
3176 throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
3179 return tasksCopy;
3182 // Throw an exception if "options" argument specifies illegal options
3183 [ContractArgumentValidatorAttribute]
3184 internal static void CheckMultiTaskContinuationOptions(TaskContinuationOptions continuationOptions)
3186 // Construct a mask to check for illegal options
3187 const TaskContinuationOptions NotOnAny = TaskContinuationOptions.NotOnCanceled |
3188 TaskContinuationOptions.NotOnFaulted |
3189 TaskContinuationOptions.NotOnRanToCompletion;
3191 // Check that LongRunning and ExecuteSynchronously are not specified together
3192 const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
3193 if ((continuationOptions & illegalMask) == illegalMask)
3195 throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_ContinueWith_ESandLR"));
3198 // Check that no nonsensical options are specified.
3199 if ((continuationOptions & ~(
3200 TaskContinuationOptions.LongRunning |
3201 TaskContinuationOptions.PreferFairness |
3202 TaskContinuationOptions.AttachedToParent |
3203 TaskContinuationOptions.DenyChildAttach |
3204 TaskContinuationOptions.HideScheduler |
3205 TaskContinuationOptions.LazyCancellation |
3206 NotOnAny |
3207 TaskContinuationOptions.ExecuteSynchronously)) != 0)
3209 throw new ArgumentOutOfRangeException("continuationOptions");
3212 // Check that no "fire" options are specified.
3213 if ((continuationOptions & NotOnAny) != 0)
3214 throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions"));
3215 Contract.EndContractBlock();