Поделиться через


TaskCompletionSource<TResult> Класс

Определение

Представляет сторону производителя Task<TResult> без подключения к делегату, предоставляя доступ к стороне потребителя через свойство Task.

generic <typename TResult>
public ref class TaskCompletionSource
public class TaskCompletionSource<TResult>
type TaskCompletionSource<'Result> = class
Public Class TaskCompletionSource(Of TResult)

Параметры типа

TResult

Тип значения результата, связанного с этим TaskCompletionSource<TResult>.

Наследование
TaskCompletionSource<TResult>

Примеры

В следующем примере показано, как использовать TaskCompletionSource<TResult>:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

class TCSDemo
{
    // Demonstrated features:
    // 		TaskCompletionSource ctor()
    // 		TaskCompletionSource.SetResult()
    // 		TaskCompletionSource.SetException()
    //		Task.Result
    // Expected results:
    // 		The attempt to get t1.Result blocks for ~1000ms until tcs1 gets signaled. 15 is printed out.
    // 		The attempt to get t2.Result blocks for ~1000ms until tcs2 gets signaled. An exception is printed out.
    static void Main()
    {
        TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>();
        Task<int> t1 = tcs1.Task;

        // Start a background task that will complete tcs1.Task
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            tcs1.SetResult(15);
        });

        // The attempt to get the result of t1 blocks the current thread until the completion source gets signaled.
        // It should be a wait of ~1000 ms.
        Stopwatch sw = Stopwatch.StartNew();
        int result = t1.Result;
        sw.Stop();

        Console.WriteLine("(ElapsedTime={0}): t1.Result={1} (expected 15) ", sw.ElapsedMilliseconds, result);

        // ------------------------------------------------------------------

        // Alternatively, an exception can be manually set on a TaskCompletionSource.Task
        TaskCompletionSource<int> tcs2 = new TaskCompletionSource<int>();
        Task<int> t2 = tcs2.Task;

        // Start a background Task that will complete tcs2.Task with an exception
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            tcs2.SetException(new InvalidOperationException("SIMULATED EXCEPTION"));
        });

        // The attempt to get the result of t2 blocks the current thread until the completion source gets signaled with either a result or an exception.
        // In either case it should be a wait of ~1000 ms.
        sw = Stopwatch.StartNew();
        try
        {
            result = t2.Result;

            Console.WriteLine("t2.Result succeeded. THIS WAS NOT EXPECTED.");
        }
        catch (AggregateException e)
        {
            Console.Write("(ElapsedTime={0}): ", sw.ElapsedMilliseconds);
            Console.WriteLine("The following exceptions have been thrown by t2.Result: (THIS WAS EXPECTED)");
            for (int j = 0; j < e.InnerExceptions.Count; j++)
            {
                Console.WriteLine("\n-------------------------------------------------\n{0}", e.InnerExceptions[j].ToString());
            }
        }
    }
}
Imports System.Diagnostics
Imports System.Threading
Imports System.Threading.Tasks

Module TCSDemo
    ' Demonstrated features:
    '   TaskCompletionSource ctor()
    '   TaskCompletionSource.SetResult()
    '   TaskCompletionSource.SetException()
    '   Task.Result
    ' Expected results:
    '   The attempt to get t1.Result blocks for ~1000ms until tcs1 gets signaled. 15 is printed out.
    '   The attempt to get t2.Result blocks for ~1000ms until tcs2 gets signaled. An exception is printed out.

    Private Sub Main()
        Dim tcs1 As New TaskCompletionSource(Of Integer)()
        Dim t1 As Task(Of Integer) = tcs1.Task

        ' Start a background task that will complete tcs1.Task
        Task.Factory.StartNew(Sub()
                                  Thread.Sleep(1000)
                                  tcs1.SetResult(15)
                              End Sub)

        ' The attempt to get the result of t1 blocks the current thread until the completion source gets signaled.
        ' It should be a wait of ~1000 ms.
        Dim sw As Stopwatch = Stopwatch.StartNew()
        Dim result As Integer = t1.Result
        sw.Stop()

        Console.WriteLine("(ElapsedTime={0}): t1.Result={1} (expected 15) ", sw.ElapsedMilliseconds, result)

        ' ------------------------------------------------------------------

        ' Alternatively, an exception can be manually set on a TaskCompletionSource.Task
        Dim tcs2 As New TaskCompletionSource(Of Integer)()
        Dim t2 As Task(Of Integer) = tcs2.Task

        ' Start a background Task that will complete tcs2.Task with an exception
        Task.Factory.StartNew(Sub()
                                  Thread.Sleep(1000)
                                  tcs2.SetException(New InvalidOperationException("SIMULATED EXCEPTION"))
                              End Sub)

        ' The attempt to get the result of t2 blocks the current thread until the completion source gets signaled with either a result or an exception.
        ' In either case it should be a wait of ~1000 ms.
        sw = Stopwatch.StartNew()
        Try
            result = t2.Result

            Console.WriteLine("t2.Result succeeded. THIS WAS NOT EXPECTED.")
        Catch e As AggregateException
            Console.Write("(ElapsedTime={0}): ", sw.ElapsedMilliseconds)
            Console.WriteLine("The following exceptions have been thrown by t2.Result: (THIS WAS EXPECTED)")
            For j As Integer = 0 To e.InnerExceptions.Count - 1
                Console.WriteLine(vbLf & "-------------------------------------------------" & vbLf & "{0}", e.InnerExceptions(j).ToString())
            Next
        End Try
    End Sub

End Module

Комментарии

Во многих сценариях полезно разрешить Task<TResult> представлять внешнюю асинхронную операцию. TaskCompletionSource<TResult> предоставляется для этой цели. Это позволяет создавать задачу, которую можно передать потребителям. Потребители могут использовать члены задачи так же, как и в любом другом сценарии, обрабатывающего переменные члена задачи. Однако, в отличие от большинства задач, состояние задачи, созданной TaskCompletionSource, контролируется явным образом методами в TaskCompletionSource. Это позволяет распространить внешнюю асинхронную операцию в базовую задачу. Разделение также гарантирует, что потребители не могут переходить состояние без доступа к соответствующему TaskCompletionSource. Дополнительные сведения см. в записи Природа taskCompletionSource<TResult> в блоге параллельного программирования с помощью .NET.

Примеры параллельных расширений также содержат примеры использования TaskCompletionSource<TResult>.

Конструкторы

TaskCompletionSource<TResult>()

Создает TaskCompletionSource<TResult>.

TaskCompletionSource<TResult>(Object)

Создает TaskCompletionSource<TResult> с указанным состоянием.

TaskCompletionSource<TResult>(Object, TaskCreationOptions)

Создает TaskCompletionSource<TResult> с указанным состоянием и параметрами.

TaskCompletionSource<TResult>(TaskCreationOptions)

Создает TaskCompletionSource<TResult> с указанными параметрами.

Свойства

Task

Возвращает Task<TResult>, созданные этим TaskCompletionSource<TResult>.

Методы

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetType()

Возвращает Type текущего экземпляра.

(Унаследовано от Object)
MemberwiseClone()

Создает неглубокую копию текущей Object.

(Унаследовано от Object)
SetCanceled()

Преобразует базовые Task<TResult> в состояние Canceled.

SetCanceled(CancellationToken)

Преобразует базовые Task<TResult> в состояние Canceled с помощью указанного маркера.

SetException(Exception)

Преобразует базовый Task<TResult> в состояние Faulted и привязывает его к указанному исключению.

SetException(IEnumerable<Exception>)

Преобразует базовый Task<TResult> в состояние Faulted и привязывает к нему коллекцию объектов исключений.

SetFromTask(Task<TResult>)

Преобразует базовый Task<TResult> в то же состояние завершения, что и указанный completedTask.

SetResult(TResult)

Преобразует базовые Task<TResult> в состояние RanToCompletion.

ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)
TrySetCanceled()

Пытается перенести базовые Task<TResult> в состояние Canceled.

TrySetCanceled(CancellationToken)

Пытается перенести базовые Task<TResult> в состояние Canceled и позволяет хранить маркер отмены в отмененной задаче.

TrySetException(Exception)

Пытается перенести базовый Task<TResult> в состояние Faulted и привязывает его к указанному исключению.

TrySetException(IEnumerable<Exception>)

Пытается перенести базовый Task<TResult> в состояние Faulted и привязывает к нему коллекцию объектов исключений.

TrySetFromTask(Task<TResult>)

Пытается перенести базовые Task<TResult> в то же состояние завершения, что и указанный completedTask.

TrySetResult(TResult)

Пытается перенести базовые Task<TResult> в состояние RanToCompletion.

Применяется к

Потокобезопасность

Все члены TaskCompletionSource<TResult> являются потокобезопасными и могут использоваться одновременно из нескольких потоков.

См. также раздел