Task Class
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Represents an asynchronous operation.
public ref class Task : IAsyncResult
public ref class Task : IAsyncResult, IDisposable
public class Task : IAsyncResult
public class Task : IAsyncResult, IDisposable
type Task = class
interface IAsyncResult
type Task = class
interface IAsyncResult
interface IDisposable
Public Class Task
Implements IAsyncResult
Public Class Task
Implements IAsyncResult, IDisposable
- Inheritance
-
Task
- Derived
- Implements
Remarks
The Task class represents a single operation that does not return a value and that usually executes asynchronously. Task objects are one of the central components of the task-based asynchronous pattern first introduced in the .NET Framework 4. Because the work performed by a Task object typically executes asynchronously on a thread pool thread rather than synchronously on the main application thread, you can use the Status property, as well as the IsCanceled, IsCompleted, and IsFaulted properties, to determine the state of a task. Most commonly, a lambda expression is used to specify the work that the task is to perform.
For operations that return values, you use the Task<TResult> class.
In this section:
Task instantiation examples Creating and executing a task Separating task creation and execution Waiting for one or more tasks to complete Tasks and culture For debugger developers
Task instantiation
The following example creates and executes four tasks. Three tasks execute an Action<T> delegate named action
, which accepts an argument of type Object. A fourth task executes a lambda expression (an Action delegate) that is defined inline in the call to the task creation method. Each task is instantiated and run in a different way:
Task
t1
is instantiated by calling a Task class constructor, but is started by calling its Start() method only after taskt2
has started.Task
t2
is instantiated and started in a single method call by calling the TaskFactory.StartNew(Action<Object>, Object) method.Task
t3
is instantiated and started in a single method call by calling the Run(Action) method.Task
t4
is executed synchronously on the main thread by calling the RunSynchronously() method.
Because task t4
executes synchronously, it executes on the main application thread. The remaining tasks execute asynchronously typically on one or more thread pool threads.
using System;
using System.Threading;
using System.Threading.Tasks;
class Example
{
static void Main()
{
Action<object> action = (object obj) =>
{
Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, obj,
Thread.CurrentThread.ManagedThreadId);
};
// Create a task but do not start it.
Task t1 = new Task(action, "alpha");
// Construct a started task
Task t2 = Task.Factory.StartNew(action, "beta");
// Block the main thread to demonstrate that t2 is executing
t2.Wait();
// Launch t1
t1.Start();
Console.WriteLine("t1 has been launched. (Main Thread={0})",
Thread.CurrentThread.ManagedThreadId);
// Wait for the task to finish.
t1.Wait();
// Construct a started task using Task.Run.
String taskData = "delta";
Task t3 = Task.Run( () => {Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, taskData,
Thread.CurrentThread.ManagedThreadId);
});
// Wait for the task to finish.
t3.Wait();
// Construct an unstarted task
Task t4 = new Task(action, "gamma");
// Run it synchronously
t4.RunSynchronously();
// Although the task was run synchronously, it is a good practice
// to wait for it in the event exceptions were thrown by the task.
t4.Wait();
}
}
// The example displays output like the following:
// Task=1, obj=beta, Thread=3
// t1 has been launched. (Main Thread=1)
// Task=2, obj=alpha, Thread=4
// Task=3, obj=delta, Thread=3
// Task=4, obj=gamma, Thread=1
open System.Threading
open System.Threading.Tasks
let action =
fun (obj: obj) -> printfn $"Task={Task.CurrentId}, obj={obj}, Thread={Thread.CurrentThread.ManagedThreadId}"
// Create a task but do not start it.
let t1 = new Task(action, "alpha")
// Construct a started task
let t2 = Task.Factory.StartNew(action, "beta")
// Block the main thread to demonstrate that t2 is executing
t2.Wait()
// Launch t1
t1.Start()
printfn $"t1 has been launched. (Main Thread={Thread.CurrentThread.ManagedThreadId})"
// Wait for the task to finish.
t1.Wait()
// Construct a started task using Task.Run.
let taskData = "delta"
let t3 =
Task.Run(fun () -> printfn $"Task={Task.CurrentId}, obj={taskData}, Thread={Thread.CurrentThread.ManagedThreadId}")
// Wait for the task to finish.
t3.Wait()
// Construct an unstarted task
let t4 = new Task(action, "gamma")
// Run it synchronously
t4.RunSynchronously()
// Although the task was run synchronously, it is a good practice
// to wait for it in the event exceptions were thrown by the task.
t4.Wait()
// The example displays output like the following:
// Task=1, obj=beta, Thread=3
// t1 has been launched. (Main Thread=1)
// Task=2, obj=alpha, Thread=4
// Task=3, obj=delta, Thread=3
// Task=4, obj=gamma, Thread=1
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim action As Action(Of Object) =
Sub(obj As Object)
Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, obj,
Thread.CurrentThread.ManagedThreadId)
End Sub
' Construct an unstarted task
Dim t1 As New Task(action, "alpha")
' Construct a started task
Dim t2 As Task = Task.Factory.StartNew(action, "beta")
' Block the main thread to demonstrate that t2 is executing
t2.Wait()
' Launch t1
t1.Start()
Console.WriteLine("t1 has been launched. (Main Thread={0})",
Thread.CurrentThread.ManagedThreadId)
' Wait for the task to finish.
t1.Wait()
' Construct a started task using Task.Run.
Dim taskData As String = "delta"
Dim t3 As Task = Task.Run(Sub()
Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, taskData,
Thread.CurrentThread.ManagedThreadId)
End Sub)
' Wait for the task to finish.
t3.Wait()
' Construct an unstarted task
Dim t4 As New Task(action, "gamma")
' Run it synchronously
t4.RunSynchronously()
' Although the task was run synchronously, it is a good practice
' to wait for it in the event exceptions were thrown by the task.
t4.Wait()
End Sub
End Module
' The example displays output like the following:
' Task=1, obj=beta, Thread=3
' t1 has been launched. (Main Thread=1)
' Task=2, obj=alpha, Thread=3
' Task=3, obj=delta, Thread=3
' Task=4, obj=gamma, Thread=1
Creating and executing a task
Task instances may be created in a variety of ways. The most common approach, which is available starting with the .NET Framework 4.5, is to call the static Run method. The Run method provides a simple way to start a task using default values and without requiring additional parameters. The following example uses the Run(Action) method to start a task that loops and then displays the number of loop iterations:
using System;
using System.Threading.Tasks;
public class Example
{
public static async Task Main()
{
await Task.Run( () => {
// Just loop.
int ctr = 0;
for (ctr = 0; ctr <= 1000000; ctr++)
{}
Console.WriteLine("Finished {0} loop iterations",
ctr);
} );
}
}
// The example displays the following output:
// Finished 1000001 loop iterations
open System.Threading.Tasks
let main =
task {
do!
Task.Run(fun () ->
for i = 0 to 1000000 do
printfn $"Finished {i} loop iterations")
}
main.Wait()
// The example displays the following output:
// Finished 1000001 loop iterations
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim t As Task = Task.Run(Sub()
' Just loop.
Dim ctr As Integer = 0
For ctr = 0 to 1000000
Next
Console.WriteLine("Finished {0} loop iterations",
ctr)
End Sub)
t.Wait()
End Sub
End Module
' The example displays the following output:
' Finished 1000001 loop iterations
An alternative, and the most common method to start a task in .NET Framework 4, is the static TaskFactory.StartNew method. The Task.Factory property returns a TaskFactory object. Overloads of the TaskFactory.StartNew method let you specify parameters to pass to the task creation options and a task scheduler. The following example uses the TaskFactory.StartNew method to start a task. It is functionally equivalent to the code in the previous example.
using System;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
Task t = Task.Factory.StartNew( () => {
// Just loop.
int ctr = 0;
for (ctr = 0; ctr <= 1000000; ctr++)
{}
Console.WriteLine("Finished {0} loop iterations",
ctr);
} );
t.Wait();
}
}
// The example displays the following output:
// Finished 1000001 loop iterations
open System.Threading.Tasks
let t =
Task.Factory.StartNew(fun () ->
// Just loop.
for i = 0 to 1000000 do
printfn $"Finished {i} loop iterations")
t.Wait()
// The example displays the following output:
// Finished 1000001 loop iterations
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim t As Task = Task.Factory.StartNew(Sub()
' Just loop.
Dim ctr As Integer = 0
For ctr = 0 to 1000000
Next
Console.WriteLine("Finished {0} loop iterations",
ctr)
End Sub)
t.Wait()
End Sub
End Module
' The example displays the following output:
' Finished 1000001 loop iterations
For more complete examples, see Task-based Asynchronous Programming.
Separating task creation and execution
The Task class also provides constructors that initialize the task but that do not schedule it for execution. For performance reasons, the Task.Run or TaskFactory.StartNew method is the preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation and scheduling must be separated, you can use the constructors and then call the Task.Start method to schedule the task for execution at a later time.
Waiting for one or more tasks to complete
Because tasks typically run asynchronously on a thread pool thread, the thread that creates and starts the task continues execution as soon as the task has been instantiated. In some cases, when the calling thread is the main application thread, the app may terminate before the task actually begins execution. In others, your application's logic may require that the calling thread continue execution only when one or more tasks have completed execution. You can synchronize the execution of the calling thread and the asynchronous tasks it launches by calling a Wait
method to wait for one or more tasks to complete.
To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution.
The following example calls the parameterless Wait() method to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static Random rand = new Random();
static void Main()
{
// Wait on a single task with no timeout specified.
Task taskA = Task.Run( () => Thread.Sleep(2000));
Console.WriteLine("taskA Status: {0}", taskA.Status);
try {
taskA.Wait();
Console.WriteLine("taskA Status: {0}", taskA.Status);
}
catch (AggregateException) {
Console.WriteLine("Exception in taskA.");
}
}
}
// The example displays output like the following:
// taskA Status: WaitingToRun
// taskA Status: RanToCompletion
open System
open System.Threading
open System.Threading.Tasks
let rand = Random()
// Wait on a single task with no timeout specified.
let taskA = Task.Run(fun () -> Thread.Sleep 2000)
printfn $"taskA Status: {taskA.Status}"
try
taskA.Wait()
printfn $"taskA Status: {taskA.Status}"
with :? AggregateException ->
printfn "Exception in taskA."
// The example displays output like the following:
// taskA Status: WaitingToRun
// taskA Status: RanToCompletion
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
' Wait on a single task with no timeout specified.
Dim taskA = Task.Run( Sub() Thread.Sleep(2000))
Console.WriteLine("taskA Status: {0}", taskA.Status)
Try
taskA.Wait()
Console.WriteLine("taskA Status: {0}", taskA.Status)
Catch e As AggregateException
Console.WriteLine("Exception in taskA.")
End Try
End Sub
End Module
' The example displays output like the following:
' taskA Status: WaitingToRun
' taskA Status: RanToCompletion
You can also conditionally wait for a task to complete. The Wait(Int32) and Wait(TimeSpan) methods block the calling thread until the task finishes or a timeout interval elapses, whichever comes first. Since the following example launches a task that sleeps for two seconds but defines a one-second timeout value, the calling thread blocks until the timeout expires and before the task has completed execution.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
// Wait on a single task with a timeout specified.
Task taskA = Task.Run( () => Thread.Sleep(2000));
try {
taskA.Wait(1000); // Wait for 1 second.
bool completed = taskA.IsCompleted;
Console.WriteLine("Task A completed: {0}, Status: {1}",
completed, taskA.Status);
if (! completed)
Console.WriteLine("Timed out before task A completed.");
}
catch (AggregateException) {
Console.WriteLine("Exception in taskA.");
}
}
}
// The example displays output like the following:
// Task A completed: False, Status: Running
// Timed out before task A completed.
open System
open System.Threading
open System.Threading.Tasks
// Wait on a single task with a timeout specified.
let taskA = Task.Run(fun () -> Thread.Sleep 2000)
try
taskA.Wait 1000 |> ignore // Wait for 1 second.
let completed = taskA.IsCompleted
printfn $"Task A completed: {completed}, Status: {taskA.Status}"
if not completed then
printfn "Timed out before task A completed."
with :? AggregateException ->
printfn "Exception in taskA."
// The example displays output like the following:
// Task A completed: False, Status: Running
// Timed out before task A completed.
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
' Wait on a single task with a timeout specified.
Dim taskA As Task = Task.Run( Sub() Thread.Sleep(2000))
Try
taskA.Wait(1000) ' Wait for 1 second.
Dim completed As Boolean = taskA.IsCompleted
Console.WriteLine("Task.Completed: {0}, Status: {1}",
completed, taskA.Status)
If Not completed Then
Console.WriteLine("Timed out before task A completed.")
End If
Catch e As AggregateException
Console.WriteLine("Exception in taskA.")
End Try
End Sub
End Module
' The example displays the following output:
' Task A completed: False, Status: Running
' Timed out before task A completed.
You can also supply a cancellation token by calling the Wait(CancellationToken) and Wait(Int32, CancellationToken) methods. If the token's IsCancellationRequested property is true
or becomes true
while the Wait method is executing, the method throws an OperationCanceledException.
In some cases, you may want to wait for the first of a series of executing tasks to complete, but don't care which task it is. For this purpose, you can call one of the overloads of the Task.WaitAny method. The following example creates three tasks, each of which sleeps for an interval determined by a random number generator. The WaitAny(Task[]) method waits for the first task to complete. The example then displays information about the status of all three tasks.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
var tasks = new Task[3];
var rnd = new Random();
for (int ctr = 0; ctr <= 2; ctr++)
tasks[ctr] = Task.Run( () => Thread.Sleep(rnd.Next(500, 3000)));
try {
int index = Task.WaitAny(tasks);
Console.WriteLine("Task #{0} completed first.\n", tasks[index].Id);
Console.WriteLine("Status of all tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
}
catch (AggregateException) {
Console.WriteLine("An exception occurred.");
}
}
}
// The example displays output like the following:
// Task #1 completed first.
//
// Status of all tasks:
// Task #3: Running
// Task #1: RanToCompletion
// Task #4: Running
open System
open System.Threading
open System.Threading.Tasks
let rnd = new Random()
let tasks =
[| for _ = 0 to 2 do
Task.Run(fun () -> rnd.Next(500, 3000) |> Thread.Sleep) |]
try
let index = Task.WaitAny tasks
printfn $"Task #{tasks[index].Id} completed first.\n"
printfn "Status of all tasks:"
for t in tasks do
printfn $" Task #{t.Id}: {t.Status}"
with :? AggregateException ->
printfn "An exception occurred."
// The example displays output like the following:
// Task #1 completed first.
//
// Status of all tasks:
// Task #3: Running
// Task #1: RanToCompletion
// Task #4: Running
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim tasks(2) As Task
Dim rnd As New Random()
For ctr As Integer = 0 To 2
tasks(ctr) = Task.Run( Sub() Thread.Sleep(rnd.Next(500, 3000)))
Next
Try
Dim index As Integer= Task.WaitAny(tasks)
Console.WriteLine("Task #{0} completed first.", tasks(index).Id)
Console.WriteLine()
Console.WriteLine("Status of all tasks:")
For Each t in tasks
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status)
Next
Catch e As AggregateException
Console.WriteLine("An exception occurred.")
End Try
End Sub
End Module
' The example displays output like the following:
' Task #1 completed first.
'
' Status of all tasks:
' Task #3: Running
' Task #1: RanToCompletion
' Task #4: Running
You can also wait for all of a series of tasks to complete by calling the WaitAll method. The following example creates ten tasks, waits for all ten to complete, and then displays their status.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
// Wait for all tasks to complete.
Task[] tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
tasks[i] = Task.Run(() => Thread.Sleep(2000));
}
try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred: ");
foreach (var ex in ae.Flatten().InnerExceptions)
Console.WriteLine(" {0}", ex.Message);
}
Console.WriteLine("Status of completed tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
}
}
// The example displays the following output:
// Status of completed tasks:
// Task #2: RanToCompletion
// Task #1: RanToCompletion
// Task #3: RanToCompletion
// Task #4: RanToCompletion
// Task #6: RanToCompletion
// Task #5: RanToCompletion
// Task #7: RanToCompletion
// Task #8: RanToCompletion
// Task #9: RanToCompletion
// Task #10: RanToCompletion
open System
open System.Threading
open System.Threading.Tasks
// Wait for all tasks to complete.
let tasks =
[| for _ = 0 to 9 do
Task.Run(fun () -> Thread.Sleep 2000) |]
try
Task.WaitAll tasks
with :? AggregateException as ae ->
printfn "One or more exceptions occurred: "
for ex in ae.Flatten().InnerExceptions do
printfn $" {ex.Message}"
printfn "Status of completed tasks:"
for t in tasks do
printfn $" Task #{t.Id}: {t.Status}"
// The example displays the following output:
// Status of completed tasks:
// Task #2: RanToCompletion
// Task #1: RanToCompletion
// Task #3: RanToCompletion
// Task #4: RanToCompletion
// Task #6: RanToCompletion
// Task #5: RanToCompletion
// Task #7: RanToCompletion
// Task #8: RanToCompletion
// Task #9: RanToCompletion
// Task #10: RanToCompletion
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
' Wait for all tasks to complete.
Dim tasks(9) As Task
For i As Integer = 0 To 9
tasks(i) = Task.Run( Sub() Thread.Sleep(2000) )
Next
Try
Task.WaitAll(tasks)
Catch ae As AggregateException
Console.WriteLine("One or more exceptions occurred: ")
For Each ex In ae.Flatten().InnerExceptions
Console.WriteLine(" {0}", ex.Message)
Next
End Try
Console.WriteLine("Status of completed tasks:")
For Each t in tasks
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status)
Next
End Sub
End Module
' The example displays the following output:
' Status of completed tasks:
' Task #2: RanToCompletion
' Task #1: RanToCompletion
' Task #3: RanToCompletion
' Task #4: RanToCompletion
' Task #6: RanToCompletion
' Task #5: RanToCompletion
' Task #7: RanToCompletion
' Task #8: RanToCompletion
' Task #9: RanToCompletion
' Task #10: RanToCompletion
Note that when you wait for one or more tasks to complete, any exceptions thrown in the running tasks are propagated on the thread that calls the Wait
method, as the following example shows. It launches 12 tasks, three of which complete normally and three of which throw an exception. Of the remaining six tasks, three are cancelled before they start, and three are cancelled while they are executing. Exceptions are thrown in the WaitAll method call and are handled by a try
/catch
block.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
// Create a cancellation token and cancel it.
var source1 = new CancellationTokenSource();
var token1 = source1.Token;
source1.Cancel();
// Create a cancellation token for later cancellation.
var source2 = new CancellationTokenSource();
var token2 = source2.Token;
// Create a series of tasks that will complete, be cancelled,
// timeout, or throw an exception.
Task[] tasks = new Task[12];
for (int i = 0; i < 12; i++)
{
switch (i % 4)
{
// Task should run to completion.
case 0:
tasks[i] = Task.Run(() => Thread.Sleep(2000));
break;
// Task should be set to canceled state.
case 1:
tasks[i] = Task.Run( () => Thread.Sleep(2000),
token1);
break;
case 2:
// Task should throw an exception.
tasks[i] = Task.Run( () => { throw new NotSupportedException(); } );
break;
case 3:
// Task should examine cancellation token.
tasks[i] = Task.Run( () => { Thread.Sleep(2000);
if (token2.IsCancellationRequested)
token2.ThrowIfCancellationRequested();
Thread.Sleep(500); }, token2);
break;
}
}
Thread.Sleep(250);
source2.Cancel();
try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred:");
foreach (var ex in ae.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name, ex.Message);
}
Console.WriteLine("\nStatus of tasks:");
foreach (var t in tasks) {
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
if (t.Exception != null) {
foreach (var ex in t.Exception.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name,
ex.Message);
}
}
}
}
// The example displays output like the following:
// One or more exceptions occurred:
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
//
// Status of tasks:
// Task #13: RanToCompletion
// Task #1: Canceled
// Task #3: Faulted
// NotSupportedException: Specified method is not supported.
// Task #8: Canceled
// Task #14: RanToCompletion
// Task #4: Canceled
// Task #6: Faulted
// NotSupportedException: Specified method is not supported.
// Task #7: Canceled
// Task #15: RanToCompletion
// Task #9: Canceled
// Task #11: Faulted
// NotSupportedException: Specified method is not supported.
// Task #12: Canceled
open System
open System.Threading
open System.Threading.Tasks
// Create a cancellation token and cancel it.
let source1 = new CancellationTokenSource()
let token1 = source1.Token
source1.Cancel()
// Create a cancellation token for later cancellation.
let source2 = new CancellationTokenSource()
let token2 = source2.Token
// Create a series of tasks that will complete, be cancelled,
// timeout, or throw an exception.
let tasks =
[| for i in 0..11 do
match i % 4 with
// Task should run to completion.
| 0 -> Task.Run(fun () -> Thread.Sleep 2000)
// Task should be set to canceled state.
| 1 -> Task.Run(fun () -> Thread.Sleep 2000, token1)
// Task should throw an exception.
| 2 -> Task.Run(fun () -> NotSupportedException())
// Task should examine cancellation token.
| _ ->
Task.Run(fun () ->
Thread.Sleep 2000
if token2.IsCancellationRequested then
token2.ThrowIfCancellationRequested()
Thread.Sleep 500, token2) |]
Thread.Sleep 250
source2.Cancel()
try
Task.WaitAll tasks
with :? AggregateException as ae ->
printfn "One or more exceptions occurred:"
for ex in ae.InnerExceptions do
printfn $" {ex.GetType().Name}: {ex.Message}"
printfn "\nStatus of tasks:"
for t in tasks do
printfn $" Task #{t.Id}: {t.Status}"
if isNull t.Exception |> not then
for ex in t.Exception.InnerExceptions do
printfn $" {ex.GetType().Name}: {ex.Message}"
// The example displays output like the following:
// One or more exceptions occurred:
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
//
// Status of tasks:
// Task #13: RanToCompletion
// Task #1: Canceled
// Task #3: Faulted
// NotSupportedException: Specified method is not supported.
// Task #8: Canceled
// Task #14: RanToCompletion
// Task #4: Canceled
// Task #6: Faulted
// NotSupportedException: Specified method is not supported.
// Task #7: Canceled
// Task #15: RanToCompletion
// Task #9: Canceled
// Task #11: Faulted
// NotSupportedException: Specified method is not supported.
// Task #12: Canceled
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Public Sub Main()
' Create a cancellation token and cancel it.
Dim source1 As New CancellationTokenSource()
Dim token1 As CancellationToken = source1.Token
source1.Cancel()
' Create a cancellation token for later cancellation.
Dim source2 As New CancellationTokenSource()
Dim token2 As CancellationToken = source2.Token
' Create a series of tasks that will complete, be cancelled,
' timeout, or throw an exception.
Dim tasks(11) As Task
For i As Integer = 0 To 11
Select Case i Mod 4
' Task should run to completion.
Case 0
tasks(i) = Task.Run( Sub() Thread.Sleep(2000))
' Task should be set to canceled state.
Case 1
tasks(i) = Task.Run( Sub() Thread.Sleep(2000), token1)
Case 2
' Task should throw an exception.
tasks(i) = Task.Run( Sub()
Throw New NotSupportedException()
End Sub)
Case 3
' Task should examine cancellation token.
tasks(i) = Task.Run( Sub()
Thread.Sleep(2000)
If token2.IsCancellationRequested
token2.ThrowIfCancellationRequested()
End If
Thread.Sleep(500)
End Sub, token2)
End Select
Next
Thread.Sleep(250)
source2.Cancel()
Try
Task.WaitAll(tasks)
Catch ae As AggregateException
Console.WriteLine("One or more exceptions occurred:")
For Each ex in ae.InnerExceptions
Console.WriteLine(" {0}: {1}", ex.GetType().Name, ex.Message)
Next
End Try
Console.WriteLine()
Console.WriteLine("Status of tasks:")
For Each t in tasks
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status)
If t.Exception IsNot Nothing Then
For Each ex in t.Exception.InnerExceptions
Console.WriteLine(" {0}: {1}", ex.GetType().Name,
ex.Message)
Next
End If
Next
End Sub
End Module
' The example displays output like the following:
' One or more exceptions occurred:
' TaskCanceledException: A task was canceled.
' NotSupportedException: Specified method is not supported.
' TaskCanceledException: A task was canceled.
' TaskCanceledException: A task was canceled.
' NotSupportedException: Specified method is not supported.
' TaskCanceledException: A task was canceled.
' TaskCanceledException: A task was canceled.
' NotSupportedException: Specified method is not supported.
' TaskCanceledException: A task was canceled.
'
' Status of tasks:
' Task #13: RanToCompletion
' Task #1: Canceled
' Task #3: Faulted
' NotSupportedException: Specified method is not supported.
' Task #8: Canceled
' Task #14: RanToCompletion
' Task #4: Canceled
' Task #6: Faulted
' NotSupportedException: Specified method is not supported.
' Task #7: Canceled
' Task #15: RanToCompletion
' Task #9: Canceled
' Task #11: Faulted
' NotSupportedException: Specified method is not supported.
' Task #12: Canceled
For more information on exception handling in task-based asynchronous operations, see Exception Handling.
Tasks and culture
Starting with desktop apps that target the .NET Framework 4.6, the culture of the thread that creates and invokes a task becomes part of the thread's context. That is, regardless of the current culture of the thread on which the task executes, the current culture of the task is the culture of the calling thread. For apps that target versions of the .NET Framework prior to the .NET Framework 4.6, the culture of the task is the culture of the thread on which the task executes. For more information, see the "Culture and task-based asynchronous operations" section in the CultureInfo topic.
Note
Store apps follow the Windows Runtime in setting and getting the default culture.
For debugger developers
For developers implementing custom debuggers, several internal and private members of task may be useful (these may change from release to release). The m_taskId
field serves as the backing store for the Id property, however accessing this field directly from a debugger may be more efficient than accessing the same value through the property's getter method (the s_taskIdCounter
counter is used to retrieve the next available ID for a task). Similarly, the m_stateFlags
field stores information about the current lifecycle stage of the task, information also accessible through the Status property. The m_action
field stores a reference to the task's delegate, and the m_stateObject
field stores the async state passed to the task by the developer. Finally, for debuggers that parse stack frames, the InternalWait
method serves a potential marker for when a task is entering a wait operation.
Constructors
Task(Action) |
Initializes a new Task with the specified action. |
Task(Action, CancellationToken) |
Initializes a new Task with the specified action and CancellationToken. |
Task(Action, CancellationToken, TaskCreationOptions) |
Initializes a new Task with the specified action and creation options. |
Task(Action, TaskCreationOptions) |
Initializes a new Task with the specified action and creation options. |
Task(Action<Object>, Object) |
Initializes a new Task with the specified action and state. |
Task(Action<Object>, Object, CancellationToken) |
Initializes a new Task with the specified action, state, and options. |
Task(Action<Object>, Object, CancellationToken, TaskCreationOptions) |
Initializes a new Task with the specified action, state, and options. |
Task(Action<Object>, Object, TaskCreationOptions) |
Initializes a new Task with the specified action, state, and options. |
Properties
AsyncState |
Gets the state object supplied when the Task was created, or null if none was supplied. |
CompletedTask |
Gets a task that has already completed successfully. |
CreationOptions |
Gets the TaskCreationOptions used to create this task. |
CurrentId |
Returns the ID of the currently executing Task. |
Exception |
Gets the AggregateException that caused the Task to end prematurely. If the Task completed successfully or has not yet thrown any exceptions, this will return |
Factory |
Provides access to factory methods for creating and configuring Task and Task<TResult> instances. |
Id |
Gets an ID for this Task instance. |
IsCanceled |
Gets whether this Task instance has completed execution due to being canceled. |
IsCompleted |
Gets a value that indicates whether the task has completed. |
IsCompletedSuccessfully |
Gets whether the task ran to completion. |
IsFaulted |
Gets whether the Task completed due to an unhandled exception. |
Status |
Gets the TaskStatus of this task. |
Methods
ConfigureAwait(Boolean) |
Configures an awaiter used to await this Task. |
ConfigureAwait(ConfigureAwaitOptions) |
Configures an awaiter used to await this Task. |
ContinueWith(Action<Task,Object>, Object) |
Creates a continuation that receives caller-supplied state information and executes when the target Task completes. |
ContinueWith(Action<Task,Object>, Object, CancellationToken) |
Creates a continuation that receives caller-supplied state information and a cancellation token and that executes asynchronously when the target Task completes. |
ContinueWith(Action<Task,Object>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Creates a continuation that receives caller-supplied state information and a cancellation token and that executes when the target Task completes. The continuation executes based on a set of specified conditions and uses a specified scheduler. |
ContinueWith(Action<Task,Object>, Object, TaskContinuationOptions) |
Creates a continuation that receives caller-supplied state information and executes when the target Task completes. The continuation executes based on a set of specified conditions. |
ContinueWith(Action<Task,Object>, Object, TaskScheduler) |
Creates a continuation that receives caller-supplied state information and executes asynchronously when the target Task completes. The continuation uses a specified scheduler. |
ContinueWith(Action<Task>) |
Creates a continuation that executes asynchronously when the target Task completes. |
ContinueWith(Action<Task>, CancellationToken) |
Creates a continuation that receives a cancellation token and executes asynchronously when the target Task completes. |
ContinueWith(Action<Task>, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Creates a continuation that executes when the target task competes according to the specified TaskContinuationOptions. The continuation receives a cancellation token and uses a specified scheduler. |
ContinueWith(Action<Task>, TaskContinuationOptions) |
Creates a continuation that executes when the target task completes according to the specified TaskContinuationOptions. |
ContinueWith(Action<Task>, TaskScheduler) |
Creates a continuation that executes asynchronously when the target Task completes. The continuation uses a specified scheduler. |
ContinueWith<TResult>(Func<Task,Object,TResult>, Object) |
Creates a continuation that receives caller-supplied state information and executes asynchronously when the target Task completes and returns a value. |
ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken) |
Creates a continuation that executes asynchronously when the target Task completes and returns a value. The continuation receives caller-supplied state information and a cancellation token. |
ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Creates a continuation that executes based on the specified task continuation options when the target Task completes and returns a value. The continuation receives caller-supplied state information and a cancellation token and uses the specified scheduler. |
ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskContinuationOptions) |
Creates a continuation that executes based on the specified task continuation options when the target Task completes. The continuation receives caller-supplied state information. |
ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskScheduler) |
Creates a continuation that executes asynchronously when the target Task completes. The continuation receives caller-supplied state information and uses a specified scheduler. |
ContinueWith<TResult>(Func<Task,TResult>) |
Creates a continuation that executes asynchronously when the target Task<TResult> completes and returns a value. |
ContinueWith<TResult>(Func<Task,TResult>, CancellationToken) |
Creates a continuation that executes asynchronously when the target Task completes and returns a value. The continuation receives a cancellation token. |
ContinueWith<TResult>(Func<Task,TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Creates a continuation that executes according to the specified continuation options and returns a value. The continuation is passed a cancellation token and uses a specified scheduler. |
ContinueWith<TResult>(Func<Task,TResult>, TaskContinuationOptions) |
Creates a continuation that executes according to the specified continuation options and returns a value. |
ContinueWith<TResult>(Func<Task,TResult>, TaskScheduler) |
Creates a continuation that executes asynchronously when the target Task completes and returns a value. The continuation uses a specified scheduler. |
Delay(Int32) |
Creates a task that completes after a specified number of milliseconds. |
Delay(Int32, CancellationToken) |
Creates a cancellable task that completes after a specified number of milliseconds. |
Delay(TimeSpan) |
Creates a task that completes after a specified time interval. |
Delay(TimeSpan, CancellationToken) |
Creates a cancellable task that completes after a specified time interval. |
Delay(TimeSpan, TimeProvider) |
Creates a task that completes after a specified time interval. |
Delay(TimeSpan, TimeProvider, CancellationToken) |
Creates a cancellable task that completes after a specified time interval. |
Dispose() |
Releases all resources used by the current instance of the Task class. |
Dispose(Boolean) |
Disposes the Task, releasing all of its unmanaged resources. |
Equals(Object) |
Determines whether the specified object is equal to the current object. (Inherited from Object) |
FromCanceled(CancellationToken) |
Creates a Task that's completed due to cancellation with a specified cancellation token. |
FromCanceled<TResult>(CancellationToken) |
Creates a Task<TResult> that's completed due to cancellation with a specified cancellation token. |
FromException(Exception) |
Creates a Task that has completed with a specified exception. |
FromException<TResult>(Exception) |
Creates a Task<TResult> that's completed with a specified exception. |
FromResult<TResult>(TResult) |
Creates a Task<TResult> that's completed successfully with the specified result. |
GetAwaiter() |
Gets an awaiter used to await this Task. |
GetHashCode() |
Serves as the default hash function. (Inherited from Object) |
GetType() |
Gets the Type of the current instance. (Inherited from Object) |
MemberwiseClone() |
Creates a shallow copy of the current Object. (Inherited from Object) |
Run(Action) |
Queues the specified work to run on the thread pool and returns a Task object that represents that work. |
Run(Action, CancellationToken) |
Queues the specified work to run on the thread pool and returns a Task object that represents that work. A cancellation token allows the work to be cancelled if it has not yet started. |
Run(Func<Task>) |
Queues the specified work to run on the thread pool and returns a proxy for the task returned by |
Run(Func<Task>, CancellationToken) |
Queues the specified work to run on the thread pool and returns a proxy for the task returned by |
Run<TResult>(Func<Task<TResult>>) |
Queues the specified work to run on the thread pool and returns a proxy for the |
Run<TResult>(Func<Task<TResult>>, CancellationToken) |
Queues the specified work to run on the thread pool and returns a proxy for the |
Run<TResult>(Func<TResult>) |
Queues the specified work to run on the thread pool and returns a Task<TResult> object that represents that work. A cancellation token allows the work to be cancelled if it has not yet started. |
Run<TResult>(Func<TResult>, CancellationToken) |
Queues the specified work to run on the thread pool and returns a |
RunSynchronously() |
Runs the Task synchronously on the current TaskScheduler. |
RunSynchronously(TaskScheduler) |
Runs the Task synchronously on the TaskScheduler provided. |
Start() |
Starts the Task, scheduling it for execution to the current TaskScheduler. |
Start(TaskScheduler) |
Starts the Task, scheduling it for execution to the specified TaskScheduler. |
ToString() |
Returns a string that represents the current object. (Inherited from Object) |
Wait() |
Waits for the Task to complete execution. |
Wait(CancellationToken) |
Waits for the Task to complete execution. The wait terminates if a cancellation token is canceled before the task completes. |
Wait(Int32) |
Waits for the Task to complete execution within a specified number of milliseconds. |
Wait(Int32, CancellationToken) |
Waits for the Task to complete execution. The wait terminates if a timeout interval elapses or a cancellation token is canceled before the task completes. |
Wait(TimeSpan) |
Waits for the Task to complete execution within a specified time interval. |
Wait(TimeSpan, CancellationToken) |
Waits for the Task to complete execution. |
WaitAll(Task[]) |
Waits for all of the provided Task objects to complete execution. |
WaitAll(Task[], CancellationToken) |
Waits for all of the provided Task objects to complete execution unless the wait is cancelled. |
WaitAll(Task[], Int32) |
Waits for all of the provided Task objects to complete execution within a specified number of milliseconds. |
WaitAll(Task[], Int32, CancellationToken) |
Waits for all of the provided Task objects to complete execution within a specified number of milliseconds or until the wait is cancelled. |
WaitAll(Task[], TimeSpan) |
Waits for all of the provided cancellable Task objects to complete execution within a specified time interval. |
WaitAny(Task[]) |
Waits for any of the provided Task objects to complete execution. |
WaitAny(Task[], CancellationToken) |
Waits for any of the provided Task objects to complete execution unless the wait is cancelled. |
WaitAny(Task[], Int32) |
Waits for any of the provided Task objects to complete execution within a specified number of milliseconds. |
WaitAny(Task[], Int32, CancellationToken) |
Waits for any of the provided Task objects to complete execution within a specified number of milliseconds or until a cancellation token is cancelled. |
WaitAny(Task[], TimeSpan) |
Waits for any of the provided Task objects to complete execution within a specified time interval. |
WaitAsync(CancellationToken) |
Gets a Task that will complete when this Task completes or when the specified CancellationToken has cancellation requested. |
WaitAsync(TimeSpan) |
Gets a Task that will complete when this Task completes or when the specified timeout expires. |
WaitAsync(TimeSpan, CancellationToken) |
Gets a Task that will complete when this Task completes, when the specified timeout expires, or when the specified CancellationToken has cancellation requested. |
WaitAsync(TimeSpan, TimeProvider) |
Gets a Task that will complete when this Task completes or when the specified timeout expires. |
WaitAsync(TimeSpan, TimeProvider, CancellationToken) |
Gets a Task that will complete when this Task completes, when the specified timeout expires, or when the specified CancellationToken has cancellation requested. |
WhenAll(IEnumerable<Task>) |
Creates a task that will complete when all of the Task objects in an enumerable collection have completed. |
WhenAll(Task[]) |
Creates a task that will complete when all of the Task objects in an array have completed. |
WhenAll<TResult>(IEnumerable<Task<TResult>>) |
Creates a task that will complete when all of the Task<TResult> objects in an enumerable collection have completed. |
WhenAll<TResult>(Task<TResult>[]) |
Creates a task that will complete when all of the Task<TResult> objects in an array have completed. |
WhenAny(IEnumerable<Task>) |
Creates a task that will complete when any of the supplied tasks have completed. |
WhenAny(Task, Task) |
Creates a task that will complete when either of the supplied tasks have completed. |
WhenAny(Task[]) |
Creates a task that will complete when any of the supplied tasks have completed. |
WhenAny<TResult>(IEnumerable<Task<TResult>>) |
Creates a task that will complete when any of the supplied tasks have completed. |
WhenAny<TResult>(Task<TResult>, Task<TResult>) |
Creates a task that will complete when either of the supplied tasks have completed. |
WhenAny<TResult>(Task<TResult>[]) |
Creates a task that will complete when any of the supplied tasks have completed. |
Yield() |
Creates an awaitable task that asynchronously yields back to the current context when awaited. |
Explicit Interface Implementations
IAsyncResult.AsyncWaitHandle |
Gets a WaitHandle that can be used to wait for the task to complete. |
IAsyncResult.CompletedSynchronously |
Gets an indication of whether the operation completed synchronously. |
Extension Methods
DispatcherOperationWait(Task) |
Waits indefinitely for the underlying DispatcherOperation to complete. |
DispatcherOperationWait(Task, TimeSpan) |
Waits for the specified amount of time for the underlying DispatcherOperation to complete. |
IsDispatcherOperationTask(Task) |
Returns a value that indicates whether this Task is associated with a DispatcherOperation. |
AsAsyncAction(Task) |
Returns a Windows Runtime asynchronous action that represents a started task. |
Applies to
Thread Safety
All members of Task, except for Dispose(), are thread-safe and may be used from multiple threads concurrently.