Task Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Представляет асинхронную операцию.
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 представляет одну операцию, которая не возвращает значение и обычно выполняется асинхронно. Task объекты являются одним из центральных компонентов асинхронного шаблона на основе задач. Так как работа, выполняемая объектом Task, обычно выполняется асинхронно в пулах потоков, а не синхронно в основном потоке приложения, можно использовать свойство Status, а также свойства IsCanceled, IsCompleted и IsFaulted для определения состояния задачи. Чаще всего лямбда-выражение используется для указания работы, выполняемой задачей.
Для операций, возвращающих значения, используется Task<TResult> класс.
Создание экземпляра задачи
В следующем примере создаются и выполняются четыре задачи. Три задачи выполняются с помощью делегата Action<T>, именем action, принимающего аргумент типа Object. Четвертая задача выполняет лямбда-выражение (Action делегат), которое определяется непосредственно в вызове метода создания задачи. Каждая задача создается и выполняется по-другому:
Задача создается путем вызова конструктора класса task
t1, но запускается путем вызова метода Start() только после запуска задачиt2.Задача
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 Example2
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 можно создавать различными способами. Наиболее распространенный подход заключается в вызове статического 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 {
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 Example1
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
Альтернативой является статический TaskFactory.StartNew метод. Свойство 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 Example3
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
Дополнительные полные примеры см. в статье "Асинхронное программирование на основе задач".
Отдельное создание и выполнение задачи
Класс 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}"
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 Example4
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
Вы также можете условно ждать завершения задачи. Методы 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)
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 Example5
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.
Вы также можете предоставить маркер отмены, вызвав методы Wait(CancellationToken) и Wait(Int32, CancellationToken). Если свойство токена IsCancellationRequested равно true или становится true в ходе выполнения метода Wait, метод вызывает исключение OperationCanceledException.
В некоторых случаях может потребоваться дождаться завершения первой серии выполняемых задач, но не волнуйтесь, какая задача это. Для этого можно вызвать одну из перегрузок 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) |]
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 Example8
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
Вы также можете дождаться завершения всей серии задач, вызвав WaitAll метод. В следующем примере создаются десять задач, ожидает завершения всех десяти задач, а затем отображается их состояние.
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 Example6
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
Обратите внимание, что при ожидании завершения одной или нескольких задач все исключения, создаваемые в выполняемых задачах, распространяются в потоке, который вызывает Wait метод, как показано в следующем примере. Он запускает 12 задач, три из которых выполняются обычно и три из которых вызывают исключение. Из оставшихся шести задач три отменяются до их запуска, а три отменяются при выполнении. Исключения выбрасываются в вызове метода 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()
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 Example7
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 Then
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
Дополнительные сведения об обработке исключений в асинхронных операциях на основе задач см. в разделе "Обработка исключений".
Задачи и культура
Начиная с настольных приложений, предназначенных для .NET Framework 4.6, культура потока, который создает и вызывает задачу, становится частью контекста этого потока. То есть независимо от текущей культуры потока, на котором выполняется задача, текущая культура задачи — это культура вызывающего потока. Для приложений, предназначенных для версий .NET Framework до .NET Framework 4.6, культура задачи соответствует культуре потока, на котором выполняется задача. Для получения дополнительной информации см. раздел CultureInfo «Культура и асинхронные операции на основе задач».
Замечание
Приложения Магазина устанавливают и получают культуру по умолчанию, следуя среде выполнения среда выполнения Windows.
Для разработчиков, занимающихся отладкой
Для разработчиков, создающих пользовательские отладчики, несколько внутренних и закрытых членов задачи могут быть полезны (они могут изменяться от версии к версии). Поле m_taskId служит резервным хранилищем для Id свойства, однако доступ к этому полю непосредственно из отладчика может быть более эффективным, чем доступ к тому же значению через метод получения свойства ( s_taskIdCounter счетчик используется для получения следующего доступного идентификатора для задачи). Аналогичным образом m_stateFlags поле хранит сведения о текущем этапе жизненного цикла задачи, сведения также доступны через Status свойство. Поле m_action сохраняет ссылку на делегат задачи, а m_stateObject поле сохраняет асинхронное состояние, переданное разработчику. Наконец, для отладчиков, которые анализируют кадры стека, метод InternalWait служит потенциальным маркером, когда задача вступает в операцию ожидания.
Конструкторы
| Имя | Описание |
|---|---|
| Task(Action, CancellationToken, TaskCreationOptions) |
Инициализирует новый Task с указанными параметрами действия и создания. |
| Task(Action, CancellationToken) |
Инициализирует новое Task с указанным действием и CancellationToken. |
| Task(Action, TaskCreationOptions) |
Инициализирует новый Task с указанными параметрами действия и создания. |
| Task(Action) |
Инициализирует новый Task с указанным действием. |
| Task(Action<Object>, Object, CancellationToken, TaskCreationOptions) |
Инициализирует новый Task с указанным действием, состоянием и параметрами. |
| Task(Action<Object>, Object, CancellationToken) |
Инициализирует новое Task с указанным действием, состоянием и CancellationToken. |
| Task(Action<Object>, Object, TaskCreationOptions) |
Инициализирует новый Task с указанным действием, состоянием и параметрами. |
| Task(Action<Object>, Object) |
Инициализирует новое Task с указанным действием и состоянием. |
Свойства
| Имя | Описание |
|---|---|
| AsyncState |
Возвращает объект состояния, предоставленный при Task создании, или значение NULL, если он не был предоставлен. |
| CompletedTask |
Возвращает задачу, которая уже завершилась успешно. |
| CreationOptions |
Возвращает используемый TaskCreationOptions для создания этой задачи. |
| CurrentId |
Возвращает идентификатор выполняемого Taskв настоящее время. |
| Exception |
Возвращает значение AggregateException , которое привело к преждевременному Task завершению.
Task Если завершено успешно или еще не создано никаких исключений, возвращается |
| Factory |
Предоставляет доступ к методам фабрики для создания и настройки Task экземпляров Task<TResult> . |
| Id |
Возвращает идентификатор для этого Task экземпляра. |
| IsCanceled |
Получает, завершилось ли выполнение этого Task экземпляра из-за отмены. |
| IsCompleted |
Возвращает значение, указывающее, завершена ли задача. |
| IsCompletedSuccessfully |
Возвращает, выполняется ли задача до завершения. |
| IsFaulted |
Возвращает значение Task , выполненное из-за необработанного исключения. |
| Status |
TaskStatus Возвращает эту задачу. |
Методы
| Имя | Описание |
|---|---|
| ConfigureAwait(Boolean) |
Настраивает средство ожидания, используемое для ожидания этого Task. |
| ConfigureAwait(ConfigureAwaitOptions) |
Настраивает средство ожидания, используемое для ожидания этого Task. |
| ContinueWith(Action<Task,Object>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим абонентом, и маркер отмены, и выполняется после завершения целевого объекта Task . Продолжение выполняется на основе набора указанных условий и использует указанный планировщик. |
| ContinueWith(Action<Task,Object>, Object, CancellationToken) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим абонентом, и маркер отмены и выполняется асинхронно при завершении целевого объекта Task . |
| ContinueWith(Action<Task,Object>, Object, TaskContinuationOptions) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим пользователем, и выполняется после завершения целевого объекта Task . Продолжение выполняется на основе набора указанных условий. |
| ContinueWith(Action<Task,Object>, Object, TaskScheduler) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим пользователем, и выполняется асинхронно после завершения целевого объекта Task . Продолжение использует указанный планировщик. |
| ContinueWith(Action<Task,Object>, Object) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим пользователем, и выполняется после завершения целевого объекта Task . |
| ContinueWith(Action<Task>, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Создает продолжение, которое выполняется при конкуренции целевой задачи в соответствии с указанным TaskContinuationOptions. Продолжение получает маркер отмены и использует указанный планировщик. |
| ContinueWith(Action<Task>, CancellationToken) |
Создает продолжение, которое получает маркер отмены и выполняется асинхронно после завершения целевого объекта Task . |
| ContinueWith(Action<Task>, TaskContinuationOptions) |
Создает продолжение, которое выполняется, когда целевая задача завершается в соответствии с указанным TaskContinuationOptions. |
| ContinueWith(Action<Task>, TaskScheduler) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task . Продолжение использует указанный планировщик. |
| ContinueWith(Action<Task>) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task . |
| ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Создает продолжение, которое выполняется на основе указанных параметров продолжения задачи, когда целевой объект Task завершается и возвращает значение. Продолжение получает сведения о состоянии, предоставленное вызывающим абонентом, и маркер отмены и использует указанный планировщик. |
| ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task и возвращает значение. Продолжение получает сведения о состоянии, предоставленные вызывающим абонентом, и маркер отмены. |
| ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskContinuationOptions) |
Создает продолжение, которое выполняется на основе указанных параметров продолжения задачи при завершении целевого объекта Task . Продолжение получает сведения о состоянии, предоставленные вызывающим абонентом. |
| ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskScheduler) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task . Продолжение получает сведения о состоянии, предоставленные вызывающим абонентом, и использует указанный планировщик. |
| ContinueWith<TResult>(Func<Task,Object,TResult>, Object) |
Создает продолжение, которое получает сведения о состоянии, предоставленное вызывающим абонентом, и выполняется асинхронно после завершения целевого объекта Task и возвращает значение. |
| ContinueWith<TResult>(Func<Task,TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) |
Создает продолжение, которое выполняется в соответствии с указанными параметрами продолжения и возвращает значение. Продолжение передается маркер отмены и использует указанный планировщик. |
| ContinueWith<TResult>(Func<Task,TResult>, CancellationToken) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task и возвращает значение. Продолжение получает маркер отмены. |
| ContinueWith<TResult>(Func<Task,TResult>, TaskContinuationOptions) |
Создает продолжение, которое выполняется в соответствии с указанными параметрами продолжения и возвращает значение. |
| ContinueWith<TResult>(Func<Task,TResult>, TaskScheduler) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task и возвращает значение. Продолжение использует указанный планировщик. |
| ContinueWith<TResult>(Func<Task,TResult>) |
Создает продолжение, которое выполняется асинхронно при завершении целевого объекта Task<TResult> и возвращает значение. |
| Delay(Int32, CancellationToken) |
Создает отмененную задачу, которая завершается после указанного числа миллисекунда. |
| Delay(Int32) |
Создает задачу, которая завершается после указанного числа миллисекунда. |
| Delay(TimeSpan, CancellationToken) |
Создает отмененную задачу, которая завершается после указанного интервала времени. |
| Delay(TimeSpan, TimeProvider, CancellationToken) |
Создает отмененную задачу, которая завершается после указанного интервала времени. |
| Delay(TimeSpan, TimeProvider) |
Создает задачу, которая завершается после указанного интервала времени. |
| Delay(TimeSpan) |
Создает задачу, которая завершается после указанного интервала времени. |
| Dispose() |
Освобождает все ресурсы, используемые текущим экземпляром класса Task. |
| Dispose(Boolean) |
TaskУдаляет все неуправляемые ресурсы. |
| Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
| FromCanceled(CancellationToken) |
Создает завершенное Task из-за отмены с указанным маркером отмены. |
| FromCanceled<TResult>(CancellationToken) |
Создает завершенное Task<TResult> из-за отмены с указанным маркером отмены. |
| FromException(Exception) |
Создает объект, завершенный Task с указанным исключением. |
| FromException<TResult>(Exception) |
Создает объект, завершенный Task<TResult> с указанным исключением. |
| FromResult<TResult>(TResult) |
Создает успешно завершенное Task<TResult> действие с указанным результатом. |
| GetAwaiter() |
Получает средство ожидания, используемое для ожидания этого Task. |
| GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
| GetType() |
Возвращает Type текущего экземпляра. (Унаследовано от Object) |
| MemberwiseClone() |
Создает неглубокую копию текущей Object. (Унаследовано от Object) |
| Run(Action, CancellationToken) |
Очереди указанной работы, выполняемой Task в пуле потоков, и возвращает объект, представляющий работу. Маркер отмены позволяет отменить работу, если она еще не запущена. |
| Run(Action) |
Очереди указанной работы, выполняемой Task в пуле потоков, и возвращает объект, представляющий работу. |
| Run(Func<Task>, CancellationToken) |
Очереди указанной работы, выполняемой в пуле потоков, и возвращает прокси-сервер для задачи, возвращаемой |
| Run(Func<Task>) |
Очереди указанной работы, выполняемой в пуле потоков, и возвращает прокси-сервер для задачи, возвращаемой |
| Run<TResult>(Func<Task<TResult>>, CancellationToken) |
Очереди указанной работы, выполняемой в пуле потоков, и возвращает прокси-сервер для возвращаемого |
| Run<TResult>(Func<Task<TResult>>) |
Очереди указанной работы, выполняемой в пуле потоков, и возвращает прокси-сервер для возвращаемого |
| Run<TResult>(Func<TResult>, CancellationToken) |
Очереди указанной работы, выполняемой |
| Run<TResult>(Func<TResult>) |
Очереди указанной работы, выполняемой Task<TResult> в пуле потоков, и возвращает объект, представляющий работу. Маркер отмены позволяет отменить работу, если она еще не запущена. |
| RunSynchronously() |
Task Выполняется синхронно в текущемTaskScheduler. |
| RunSynchronously(TaskScheduler) |
Task Выполняется синхронно на предоставленном объектеTaskScheduler. |
| Start() |
TaskЗапускает , планируя его для выполнения в текущий TaskSchedulerмомент. |
| Start(TaskScheduler) |
TaskЗапускает , планируя его для выполнения в указанныйTaskScheduler. |
| ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
| Wait() |
Task Ожидает завершения выполнения. |
| Wait(CancellationToken) |
Task Ожидает завершения выполнения. Ожидание завершается, если маркер отмены отменен до завершения задачи. |
| Wait(Int32, CancellationToken) |
Task Ожидает завершения выполнения. Ожидание завершается, если интервал времени ожидания истекает или маркер отмены отмены будет отменен до завершения задачи. |
| Wait(Int32) |
Task Ожидает завершения выполнения в пределах указанного числа миллисекунда. |
| Wait(TimeSpan, CancellationToken) |
Task Ожидает завершения выполнения. |
| Wait(TimeSpan) |
Task Ожидает завершения выполнения в течение указанного интервала времени. |
| WaitAll(IEnumerable<Task>, CancellationToken) |
Ожидает завершения выполнения всех предоставленных Task объектов, если ожидание не отменено. |
| WaitAll(ReadOnlySpan<Task>) |
Ожидает завершения выполнения всех предоставленных Task объектов. |
| WaitAll(Task[], CancellationToken) |
Ожидает завершения выполнения всех предоставленных Task объектов, если ожидание не отменено. |
| WaitAll(Task[], Int32, CancellationToken) |
Ожидает завершения выполнения всех предоставленных Task объектов в пределах указанного количества миллисекунда или до отмены ожидания. |
| WaitAll(Task[], Int32) |
Ожидает завершения выполнения всех предоставленных Task объектов в пределах указанного числа миллисекунда. |
| WaitAll(Task[], TimeSpan) |
Ожидает завершения выполнения всех предоставленных объектов с возможностью Task отмены в течение указанного интервала времени. |
| WaitAll(Task[]) |
Ожидает завершения выполнения всех предоставленных Task объектов. |
| WaitAny(Task[], CancellationToken) |
Ожидает завершения выполнения любого из предоставленных Task объектов, если ожидание не отменено. |
| WaitAny(Task[], Int32, CancellationToken) |
Ожидает завершения выполнения любого из предоставленных Task объектов в пределах указанного количества миллисекунда или до отмены маркера отмены. |
| WaitAny(Task[], Int32) |
Ожидает завершения выполнения любого из предоставленных Task объектов в пределах указанного числа миллисекунда. |
| WaitAny(Task[], TimeSpan) |
Ожидает завершения выполнения любого из предоставленных Task объектов в течение указанного интервала времени. |
| WaitAny(Task[]) |
Ожидает завершения выполнения любого из предоставленных Task объектов. |
| WaitAsync(CancellationToken) |
Возвращает значение Task , которое завершится, когда это Task завершится или когда указан CancellationToken запрос на отмену. |
| WaitAsync(TimeSpan, CancellationToken) |
Возвращает значение Task , которое завершится, когда Task истекает указанное время ожидания или когда указанный CancellationToken запрос на отмену запрошен. |
| WaitAsync(TimeSpan, TimeProvider, CancellationToken) |
Возвращает значение Task , которое завершится, когда Task истекает указанное время ожидания или когда указанный CancellationToken запрос на отмену запрошен. |
| WaitAsync(TimeSpan, TimeProvider) |
Получает значение Task , которое завершится, когда это Task завершится или когда истекает указанное время ожидания. |
| WaitAsync(TimeSpan) |
Получает значение Task , которое завершится, когда это Task завершится или когда истекает указанное время ожидания. |
| WhenAll(IEnumerable<Task>) |
Создает задачу, которая завершится после завершения всех Task объектов в перечисленной коллекции. |
| WhenAll(ReadOnlySpan<Task>) |
Создает задачу, которая завершится после завершения всех предоставленных задач. |
| WhenAll(Task[]) |
Создает задачу, которая завершится после завершения всех Task объектов в массиве. |
| WhenAll<TResult>(IEnumerable<Task<TResult>>) |
Создает задачу, которая завершится после завершения всех Task<TResult> объектов в перечисленной коллекции. |
| WhenAll<TResult>(ReadOnlySpan<Task<TResult>>) |
Создает задачу, которая завершится после завершения всех предоставленных задач. |
| WhenAll<TResult>(Task<TResult>[]) |
Создает задачу, которая завершится после завершения всех Task<TResult> объектов в массиве. |
| WhenAny(IEnumerable<Task>) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny(ReadOnlySpan<Task>) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny(Task, Task) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny(Task[]) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny<TResult>(IEnumerable<Task<TResult>>) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny<TResult>(ReadOnlySpan<Task<TResult>>) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny<TResult>(Task<TResult>, Task<TResult>) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenAny<TResult>(Task<TResult>[]) |
Создает задачу, которая завершится после завершения любой из предоставленных задач. |
| WhenEach(IEnumerable<Task>) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| WhenEach(ReadOnlySpan<Task>) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| WhenEach(Task[]) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| WhenEach<TResult>(IEnumerable<Task<TResult>>) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| WhenEach<TResult>(ReadOnlySpan<Task<TResult>>) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| WhenEach<TResult>(Task<TResult>[]) |
Создает объект IAsyncEnumerable<T> , который даст предоставленные задачи по мере выполнения этих задач. |
| Yield() |
Создает ожидаемую задачу, которая асинхронно возвращает текущий контекст при ожидании. |
Явные реализации интерфейса
| Имя | Описание |
|---|---|
| IAsyncResult.AsyncWaitHandle |
Получает значение WaitHandle , которое можно использовать для ожидания завершения задачи. |
| IAsyncResult.CompletedSynchronously |
Получает указание на то, выполняется ли операция синхронно. |
Методы расширения
| Имя | Описание |
|---|---|
| AsAsyncAction(Task) |
Возвращает асинхронное действие среды выполнения Windows, представляющее запущенную задачу. |
| DispatcherOperationWait(Task, TimeSpan) |
Ожидает завершения указанного периода времени DispatcherOperation . |
| DispatcherOperationWait(Task) |
Ожидает бесконечного завершения базовой DispatcherOperation базы данных. |
| IsDispatcherOperationTask(Task) |
Возвращает значение, указывающее, связана ли эта Task функция с DispatcherOperation. |
Применяется к
Потокобезопасность
Все члены Task, за исключением Dispose(), являются потокобезопасными и могут использоваться из нескольких потоков одновременно.