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
类
Task
表示不返回值且通常异步执行的单个操作。
Task
对象是.NET Framework 4 中首次引入的
基于任务的异步模式
的核心组件之一。 由于对象执行
Task
的工作通常在线程池线程上异步执行,而不是在主应用程序线程上同步执行,因此可以使用
Status
属性以及
IsCanceled
、
IsCompleted
和
IsFaulted
属性来确定任务的状态。 大多数情况下,lambda 表达式用于指定任务要执行的工作。
对于返回值的操作,请使用
Task<TResult>
类。
本部分内容:
任务实例化示例
创建和执行任务
分离任务创建和执行
等待一个或多个任务完成
任务和区域性
面向调试器开发人员
任务实例化
以下示例创建并执行四个任务。 三个任务执行名为
Action<T>
action
的委托,该委托接受类型
Object
为 的参数。 第四个任务 (
Action
委托) 执行 lambda 表达式,该委托在对任务创建方法的调用中内联定义。 每个任务都以不同的方式实例化并运行:
任务
t1
通过调用 Task 类构造函数进行实例化,但仅在任务
t2
启动后调用其
Start()
方法启动。
任务
t2
通过调用
TaskFactory.StartNew(Action<Object>, Object)
方法在单个方法调用中实例化和启动。
任务
t3
通过调用
Run(Action)
方法在单个方法调用中实例化和启动。
任务
t4
通过调用
RunSynchronously()
方法在主线程上同步执行。
由于任务
t4
以同步方式执行,因此它会在主应用程序线程上执行。 其余任务通常在一个或多个线程池线程上异步执行。
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
创建和执行任务
Task
可以通过多种方式创建实例。 从 .NET Framework 4.5 开始,最常见的方法是调用静态
Run
方法。 方法
Run
提供了一种使用默认值启动任务的简单方法,而无需其他参数。 以下示例使用
Run(Action)
方法启动循环任务,然后显示循环迭代次数:
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 {
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
Console.WriteLine("Finished {0} loop iterations",
End Sub)
t.Wait()
End Sub
End Module
' The example displays the following output:
' Finished 1000001 loop iterations
另一种方法是静态
TaskFactory.StartNew
方法,也是在 .NET Framework 4 中启动任务的最常见方法。 属性
Task.Factory
返回 对象
TaskFactory
。 方法的
TaskFactory.StartNew
重载使你可以指定要传递给任务创建选项和任务计划程序的参数。 以下示例使用
TaskFactory.StartNew
方法启动任务。 它在功能上等效于上一示例中的代码。
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
Console.WriteLine("Finished {0} loop iterations",
End Sub)
t.Wait()
End Sub
End Module
' The example displays the following output:
' Finished 1000001 loop iterations
有关更完整的示例,请参阅
基于任务的异步编程
。
分离任务创建和执行
类
Task
还提供用于初始化任务但不安排任务的执行任务的构造函数。 出于性能原因,
Task.Run
或
TaskFactory.StartNew
方法是创建和计划计算任务的首选机制,但对于必须分离创建和计划的方案,可以使用 构造函数,然后调用
Task.Start
方法以计划任务以供以后执行。
等待一个或多个任务完成
由于任务通常在线程池线程上异步运行,因此创建和启动任务的线程在实例化任务后立即继续执行。 在某些情况下,当调用线程是主应用程序线程时,应用可能会在任务实际开始执行之前终止。 在其他人中,应用程序的逻辑可能要求调用线程仅在一个或多个任务完成执行时继续执行。 可以通过调用
Wait
方法来等待一个或多个任务完成,来同步调用线程及其启动的异步任务的执行。
若要等待单个任务完成,可以调用其
Task.Wait
方法。 对 方法的
Wait
调用会阻止调用线程,直到单个类实例完成执行。
以下示例调用无
Wait()
参数方法以无条件地等待任务完成。 该任务通过调用
Thread.Sleep
方法休眠两秒钟来模拟工作。
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}"
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)
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
还可以有条件地等待任务完成。
Wait(Int32)
和
Wait(TimeSpan)
方法会阻止调用线程,直到任务完成或超时间隔过(以先到者为准)。 由于以下示例启动一个休眠两秒但定义一秒超时值的任务,调用线程将一直阻止,直到超时到期和任务完成执行。
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)
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))
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.
还可以通过调用
Wait(CancellationToken)
和
Wait(Int32, CancellationToken)
方法提供取消令牌。 如果在执行方法时令牌的
IsCancellationRequested
属性为
true
或 变为
true
,则 该方法将
OperationCanceledException
Wait
引发 。
在某些情况下,你可能希望等待一系列执行任务中的第一个完成,但不关心它是哪个任务。 为此,可以调用 方法的重载
Task.WaitAny
之一。 以下示例创建三个任务,每个任务都按随机数生成器确定的间隔休眠。 方法
WaitAny(Task[])
等待第一个任务完成。 然后,该示例显示有关所有三个任务的状态的信息。
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) |]
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)))
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)
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
还可以通过调用
WaitAll
方法等待所有一系列任务完成。 以下示例创建 10 个任务,等待全部 10 个任务完成,然后显示其状态。
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) |]
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) )
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)
End Try
Console.WriteLine("Status of completed tasks:")
For Each t in tasks
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status)
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
请注意,在等待一个或多个任务完成时,正在运行的任务中引发的任何异常都将在调用
Wait
方法的线程上传播,如以下示例所示。 它启动 12 个任务,其中 3 个正常完成,其中 3 个引发异常。 在其余六个任务中,有 3 个在开始前取消,3 个任务在执行时取消。 异常在方法调用中
WaitAll
引发,并由
try
/
catch
块处理。
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()
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
Thread.Sleep(250)
source2.Cancel()
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)
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)
End If
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
有关基于任务的异步操作中的异常处理的详细信息,请参阅
异常处理
。
任务和区域性
从面向 .NET Framework 4.6 的桌面应用开始,创建和调用任务的线程区域性将成为线程上下文的一部分。 也就是说,无论执行任务的线程的当前区域性如何,任务的当前区域性都是调用线程的区域性。 对于面向 .NET Framework 4.6 之前.NET Framework版本的应用,任务的区域性是执行任务的线程的区域性。 有关详细信息,请参阅主题中的
CultureInfo
“区域性和基于任务的异步操作”部分。
应用商店应用遵循设置和获取默认区域性Windows 运行时。
面向调试器开发人员
对于实现自定义调试器的开发人员来说,任务的多个内部成员和私有成员可能很有用, (这些成员可能会从发布更改为发布) 。 字段
m_taskId
充当属性的
Id
后备存储,但直接从调试器访问此字段可能比通过属性的 getter 方法访问相同值更高效, (
s_taskIdCounter
计数器用于检索任务的下一个可用 ID) 。 同样,
m_stateFlags
字段存储有关任务的当前生命周期阶段的信息,也可以通过
Status
属性访问信息。 字段
m_action
存储对任务委托的引用,字段
m_stateObject
存储开发人员传递给任务的异步状态。 最后,对于分析堆栈帧的调试器,
InternalWait
方法为任务进入等待操作时提供潜在的标记。