Padrão assíncrono baseado em tarefaTask-based asynchronous pattern

O padrão assíncrono baseado em tarefa (TAP) é baseado nos System.Threading.Tasks.Task tipos e System.Threading.Tasks.Task<TResult> no System.Threading.Tasks namespace, que são usados para representar operações assíncronas arbitrárias.The task-based asynchronous pattern (TAP) is based on the System.Threading.Tasks.Task and System.Threading.Tasks.Task<TResult> types in the System.Threading.Tasks namespace, which are used to represent arbitrary asynchronous operations. O TAP é o padrão de design assíncrono recomendado para novos desenvolvimentos.TAP is the recommended asynchronous design pattern for new development.

Nomenclatura, parâmetros e tipos de retornoNaming, parameters, and return types

O TAP usa um único método para representar o início e a conclusão de uma operação assíncrona.TAP uses a single method to represent the initiation and completion of an asynchronous operation. Isso contrasta com o Modelo de programação assíncrona (APM ou IAsyncResult) e o Padrão assíncrono baseado em eventos (EAP).This contrasts with both the Asynchronous Programming Model (APM or IAsyncResult) pattern and the Event-based Asynchronous Pattern (EAP). O APM requer os métodos Begin e End.APM requires Begin and End methods. O EAP requer um método que tenha o sufixo Async e também requer um ou mais eventos, tipos delegados de manipulador de eventos e tipos derivados de EventArg.EAP requires a method that has the Async suffix and also requires one or more events, event handler delegate types, and EventArg-derived types. Os métodos assíncronos no TAP incluem o sufixo Async após o nome da operação para os métodos que retornam tipos aguardáveis, como Task, Task<TResult>, ValueTask e ValueTask<TResult>.Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types, such as Task, Task<TResult>, ValueTask, and ValueTask<TResult>. Por exemplo, uma operação Get assíncrona que retorna um Task<String> pode ser nomeada GetAsync.For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync. Se você estiver adicionando um método TAP a uma classe que já contenha o nome do método EAP com o sufixo Async, use, em vez dele, o sufixo TaskAsync.If you're adding a TAP method to a class that already contains an EAP method name with the Async suffix, use the suffix TaskAsync instead. Por exemplo, se a classe já possuir um método GetAsync, use o nome GetTaskAsync.For example, if the class already has a GetAsync method, use the name GetTaskAsync. Se um método inicia com uma operação assíncrona, mas não retorna um tipo aguardável, o nome dele deve começar com Begin, Start ou algum outro verbo que sugira que esse método não retorna nem gera o resultado da operação.If a method starts an asynchronous operation but does not return an awaitable type, its name should start with Begin, Start, or some other verb to suggest that this method does not return or throw the result of the operation.

Um método TAP retorna System.Threading.Tasks.Task ou System.Threading.Tasks.Task<TResult>, dependendo se o método síncrono correspondente retorna void ou um tipo TResult.A TAP method returns either a System.Threading.Tasks.Task or a System.Threading.Tasks.Task<TResult>, based on whether the corresponding synchronous method returns void or a type TResult.

Os parâmetros de um método TAP devem corresponder aos parâmetros de suas contrapartes síncronas e devem ser fornecidos na mesma ordem.The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. No entanto, os parâmetros out e ref são isentos dessa regra e devem ser evitados inteiramente.However, out and ref parameters are exempt from this rule and should be avoided entirely. Quaisquer dados retornados por um parâmetro out ou ref deve, em vez disso, ser retornado como parte do TResult retornado por Task<TResult> e deve usar uma tupla ou uma estrutura de dados personalizada para acomodar diversos valores.Any data that would have been returned through an out or ref parameter should instead be returned as part of the TResult returned by Task<TResult>, and should use a tuple or a custom data structure to accommodate multiple values. Além disso, considere adicionar um CancellationToken parâmetro mesmo se a contraparte síncrona do método Tap não oferecer uma.Also, consider adding a CancellationToken parameter even if the TAP method's synchronous counterpart does not offer one.

Os métodos que são dedicados exclusivamente à criação, ao tratamento ou à combinação de tarefas (onde a intenção assíncrona do método está clara no nome do método ou no nome do tipo ao qual o método pertence) não precisam seguir esse padrão de nomenclatura; esses métodos são geralmente denominados combinadores.Methods that are devoted exclusively to the creation, manipulation, or combination of tasks (where the asynchronous intent of the method is clear in the method name or in the name of the type to which the method belongs) need not follow this naming pattern; such methods are often referred to as combinators. Os exemplos de combinadores incluem WhenAll e WhenAny e são discutidos na seção Usando os combinadores baseados em tarefas internos do artigo Consumindo o padrão assíncrono baseado em tarefa.Examples of combinators include WhenAll and WhenAny, and are discussed in the Using the Built-in Task-based Combinators section of the article Consuming the Task-based Asynchronous Pattern.

Para obter exemplos de como a sintaxe do TAP difere da sintaxe usada em padrões de programação assíncronos herdados, como APM (Asynchronous Programming Model) e EAP (Event-based Asynchronous Pattern), confira Padrões de programação assíncrona .For examples of how the TAP syntax differs from the syntax used in legacy asynchronous programming patterns such as the Asynchronous Programming Model (APM) and the Event-based Asynchronous Pattern (EAP), see Asynchronous Programming Patterns.

Como iniciar uma operação assíncronaInitiating an asynchronous operation

Um método assíncrono baseado no TAP pode fazer uma pequena quantidade de trabalho de forma síncrona, como validar argumentos e iniciar a operação assíncrona, antes de retornar a tarefa resultante.An asynchronous method that is based on TAP can do a small amount of work synchronously, such as validating arguments and initiating the asynchronous operation, before it returns the resulting task. O trabalho síncrono deve ser mantido no mínimo possível para que o método assíncrono possa retornar rapidamente.Synchronous work should be kept to the minimum so the asynchronous method can return quickly. Os motivos para um retorno rápido incluem:Reasons for a quick return include:

  • Os métodos assíncronos podem ser chamados de segmentos de interface do usuário (UI), e qualquer trabalho síncrono longo pode prejudicar a resposta do aplicativo.Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • É possível iniciar vários métodos assíncronos simultaneamente.Multiple asynchronous methods may be launched concurrently. Portanto, qualquer trabalho longo na parte síncrona de um método assíncrono pode atrasar a inicialização de outras operações assíncronas, diminuindo assim os benefícios de simultaneidade.Therefore, any long-running work in the synchronous portion of an asynchronous method could delay the initiation of other asynchronous operations, thereby decreasing the benefits of concurrency.

Em alguns casos, a quantidade de trabalho necessária para concluir a operação é menor do que a quantidade de trabalho necessária para iniciar a operação de forma assíncrona.In some cases, the amount of work required to complete the operation is less than the amount of work required to launch the operation asynchronously. Ler de um fluxo em que a operação de leitura pode ser satisfeita pelos dados que já estão armazenados no buffer de memória é um exemplo de cenário desse tipo.Reading from a stream where the read operation can be satisfied by data that is already buffered in memory is an example of such a scenario. Em casos como esse, a operação pode ser concluída de forma síncrona e retornar uma tarefa que já havia sido concluída.In such cases, the operation may complete synchronously, and may return a task that has already been completed.

ExceçõesExceptions

Um método assíncrono deve gerar uma exceção para ser lançada fora da chamada do método assíncrono somente em resposta a um erro de uso.An asynchronous method should raise an exception to be thrown out of the asynchronous method call only in response to a usage error. Erros de uso nunca devem ocorrer em código de produção.Usage errors should never occur in production code. Por exemplo, se a passagem de uma referência nula ( Nothing em Visual Basic) como um dos argumentos do método causar um estado de erro (geralmente representado por uma ArgumentNullException exceção), você poderá modificar o código de chamada para garantir que uma referência nula nunca seja passada.For example, if passing a null reference (Nothing in Visual Basic) as one of the method's arguments causes an error state (usually represented by an ArgumentNullException exception), you can modify the calling code to ensure that a null reference is never passed. Para todos outros erros, as exceções que ocorrem quando um método assíncrono está em execução devem ser atribuídas a tarefa retornada, mesmo quando o método assíncrono é concluído de forma síncrona antes de a tarefa ser retornada.For all other errors, exceptions that occur when an asynchronous method is running should be assigned to the returned task, even if the asynchronous method happens to complete synchronously before the task is returned. Normalmente, uma tarefa contém no máximo uma exceção.Typically, a task contains at most one exception. No entanto, se a tarefa representa várias operações (por exemplo, WhenAll), várias exceções podem ser associadas a uma única tarefa.However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

Ambiente de destinoTarget environment

Quando você implementa um método TAP, pode determinar o local em que a execução assíncrona ocorre.When you implement a TAP method, you can determine where asynchronous execution occurs. Você pode optar por executar a carga de trabalho no pool de threads, implementá-la usando e/s assíncrona (sem estar associada a um thread para a maioria da execução da operação), executá-la em um thread específico (como o thread de interface do usuário) ou usar qualquer número de contextos potenciais.You may choose to execute the workload on the thread pool, implement it by using asynchronous I/O (without being bound to a thread for the majority of the operation's execution), run it on a specific thread (such as the UI thread), or use any number of potential contexts. Um método TAP pode até não ter nada a executar e pode retornar apenas um Task, que representa a ocorrência de uma condição em outro lugar no sistema (por exemplo, uma tarefa que representa os dados que chegam a uma estrutura de dados na fila).A TAP method may even have nothing to execute, and may just return a Task that represents the occurrence of a condition elsewhere in the system (for example, a task that represents data arriving at a queued data structure).

O chamador do método TAP pode bloquear a espera para o método TAP ser concluído com a espera síncrona na tarefa resultante ou pode executar código adicional (continuação) quando a operação assíncrona é concluída.The caller of the TAP method may block waiting for the TAP method to complete by synchronously waiting on the resulting task, or may run additional (continuation) code when the asynchronous operation completes. O criador do código de continuação tem o controle sobre o local em que o código é executado.The creator of the continuation code has control over where that code executes. Você pode criar o código de continuação explicitamente com os métodos da classe Task (por exemplo, ContinueWith) ou implicitamente usando o suporte à linguagem compilado nas continuações (por exemplo, await em C#, Await em Visual Basic, AwaitValue em F#).You may create the continuation code either explicitly, through methods on the Task class (for example, ContinueWith) or implicitly, by using language support built on top of continuations (for example, await in C#, Await in Visual Basic, AwaitValue in F#).

Status da tarefaTask status

A classe Task fornece um ciclo de vida para operações assíncronas, e esse ciclo é representado pela enumeração TaskStatus.The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. Para oferecer suporte a casos extremos de tipos que derivam de Task e de Task<TResult> e suporte à separação da construção do agendamento, a classe Task expõe um método Start.To support corner cases of types that derive from Task and Task<TResult>, and to support the separation of construction from scheduling, the Task class exposes a Start method. As tarefas que são criadas pelos construtores públicos Task são chamadas de tarefas frias, porque começam seu ciclo de vida no estado não agendado Created e são agendadas somente quando Start é chamado nessas instâncias.Tasks that are created by the public Task constructors are referred to as cold tasks, because they begin their life cycle in the non-scheduled Created state and are scheduled only when Start is called on these instances.

Todas tarefas restantes começam seu ciclo de vida em um estado quente, o que significa que as operações assíncronas que elas representam já foram iniciadas, e seus status de tarefa são um valor de enumeração diferente de TaskStatus.Created.All other tasks begin their life cycle in a hot state, which means that the asynchronous operations they represent have already been initiated and their task status is an enumeration value other than TaskStatus.Created. Todas as tarefas que são retornadas dos métodos TAP devem ser ativadas.All tasks that are returned from TAP methods must be activated. Se um método TAP usa internamente um construtor de tarefa para instanciar a tarefa a ser retornada, o método TAP deve chamar Start no Task objeto antes de retorná-lo.If a TAP method internally uses a task's constructor to instantiate the task to be returned, the TAP method must call Start on the Task object before returning it. Os consumidores de um método TAP podem presumir com segurança que a tarefa retornada está ativa e não devem tentar chamar Start em qualquer Task que é retornado de um método TAP.Consumers of a TAP method may safely assume that the returned task is active and should not try to call Start on any Task that is returned from a TAP method. A chamada Start em uma tarefa ativa resulta em uma exceção de InvalidOperationException.Calling Start on an active task results in an InvalidOperationException exception.

Cancelamento (opcional)Cancellation (optional)

Em TAP, o cancelamento é opcional para implementadores e consumidores de métodos assíncronos.In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. Se uma operação permite o cancelamento, ela expõe uma sobrecarga do método assíncrono que aceita um símbolo de cancelamento (CancellationToken).If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). Por convenção, o parâmetro é chamado cancellationToken.By convention, the parameter is named cancellationToken.

public Task ReadAsync(byte [] buffer, int offset, int count,
                      CancellationToken cancellationToken)
Public Function ReadAsync(buffer() As Byte, offset As Integer,
                          count As Integer,
                          cancellationToken As CancellationToken) _
                          As Task

A operação assíncrona monitora esse token para solicitações de cancelamento.The asynchronous operation monitors this token for cancellation requests. Se ela recebe uma solicitação de cancelamento, pode escolher honrar a solicitação e cancelar a operação.If it receives a cancellation request, it may choose to honor that request and cancel the operation. Se a solicitação de cancelamento resulta em algum trabalho ser encerrado prematuramente, o método TAP retorna uma tarefa que termina em estado de Canceled; não há nenhum resultado disponível, e nenhuma exceção é gerada.If the cancellation request results in work being ended prematurely, the TAP method returns a task that ends in the Canceled state; there is no available result and no exception is thrown. O estado Canceled é considerado um estado final (concluído) para uma tarefa, juntamente com os estados Faulted e RanToCompletion.The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. Portanto, se uma tarefa está no estado Canceled, sua propriedade IsCompleted retorna true.Therefore, if a task is in the Canceled state, its IsCompleted property returns true. Quando uma tarefa termina no estado Canceled, todas as continuações registradas com a tarefa ou agendadas são executadas, a menos que uma opção de continuação como NotOnCanceled tenha sido especificada para optar pela não continuação.When a task completes in the Canceled state, any continuations registered with the task are scheduled or executed, unless a continuation option such as NotOnCanceled was specified to opt out of continuation. Qualquer código que esteja aguardando de forma assíncrona uma tarefa cancelada com o uso de recursos de linguagem continuará a ser executada, mas receberá OperationCanceledException ou uma exceção derivada dela.Any code that is asynchronously waiting for a canceled task through use of language features continues to run but receives an OperationCanceledException or an exception derived from it. O código bloqueado que espera de forma síncrona a tarefa através de métodos como Wait e WaitAll também continuará a ser executado com uma exceção.Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

Se um token de cancelamento solicitou o cancelamento antes do método TAP que aceita esse token ter sido chamado, o método TAP deve retornar uma tarefa Canceled.If a cancellation token has requested cancellation before the TAP method that accepts that token is called, the TAP method should return a Canceled task. No entanto, se o cancelamento é solicitado enquanto a operação assíncrona é executada, a operação assíncrona não precisa aceitar a solicitação de cancelamento.However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. A tarefa retornada deverá terminar no estado Canceled somente se a operação terminar como um resultado da solicitação de cancelamento.The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. Se o cancelamento for solicitado, mas um resultado ou uma exceção ainda forem gerados, a tarefa deve terminar no estado RanToCompletion ou Faulted.If cancellation is requested but a result or an exception is still produced, the task should end in the RanToCompletion or Faulted state.

Para métodos assíncronos que desejam expor a capacidade de ser cancelada primeiro e mais importante, você não precisa fornecer uma sobrecarga que não aceite um token de cancelamento.For asynchronous methods that want to expose the ability to be canceled first and foremost, you don't have to provide an overload that doesn't accept a cancellation token. Para os métodos que não podem ser cancelados, não forneça sobrecargas que aceitem um token de cancelamento; isso ajuda a indicar ao chamador se o método de destino é realmente cancelável.For methods that cannot be canceled, do not provide overloads that accept a cancellation token; this helps indicate to the caller whether the target method is actually cancelable. O código consumidor que não deseja cancelamento pode chamar um método que aceita um CancellationToken e fornece None como o valor do argumento.Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None é funcionalmente equivalente ao CancellationToken padrão.None is functionally equivalent to the default CancellationToken.

Relatório de progresso (opcional)Progress reporting (optional)

Algumas operações assíncronas beneficiam-se do fornecimento de notificações de progresso; esses são normalmente usados para atualizar uma interface do usuário com informações sobre o andamento da operação assíncrona.Some asynchronous operations benefit from providing progress notifications; these are typically used to update a user interface with information about the progress of the asynchronous operation.

No TAP, o progresso é tratado por uma interface IProgress<T> que é passada para o método assíncrono como um parâmetro que é chamado geralmente de progress.In TAP, progress is handled through an IProgress<T> interface, which is passed to the asynchronous method as a parameter that is usually named progress. Fornecer a interface de progresso quando o método assíncrono é chamado ajuda a eliminar as condições de corrida resultantes do uso incorreto (isto é, quando os manipuladores de eventos registrados incorretamente depois que a operação é iniciada podem carecer de atualizações).Providing the progress interface when the asynchronous method is called helps eliminate race conditions that result from incorrect usage (that is, when event handlers that are incorrectly registered after the operation starts may miss updates). Mais importante, a interface de progresso suporta implementações de variação de progresso, conforme determinado pelo código consumidor.More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. Por exemplo, o código consumidor só pode importar-se com a última atualização de progresso, pode desejar armazenar em buffer todas as atualizações, pode querer chamar uma ação para cada atualização ou pode desejar controlar se a chamada é vinculada a um thread específico.For example, the consuming code may only care about the latest progress update, or may want to buffer all updates, or may want to invoke an action for each update, or may want to control whether the invocation is marshaled to a particular thread. Todas essas opções podem ser obtidas usando uma implementação diferente da interface, personalizada para as necessidades específicas do consumidor.All these options may be achieved by using a different implementation of the interface, customized to the particular consumer's needs. Assim como no cancelamento, as implementações de TAP devem fornecer um parâmetro de IProgress<T> somente se a API oferecer suporte a notificações de progresso.As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

Por exemplo, se o método ReadAsync discutido anteriormente nesse artigo for capaz de relatar o progresso intermediário na forma do número de bytes lidos até aqui, o retorno de chamada de progresso poderá ser uma interface IProgress<T>:For example, if the ReadAsync method discussed earlier in this article is able to report intermediate progress in the form of the number of bytes read thus far, the progress callback could be an IProgress<T> interface:

public Task ReadAsync(byte[] buffer, int offset, int count,
                      IProgress<long> progress)
Public Function ReadAsync(buffer() As Byte, offset As Integer,
                          count As Integer,
                          progress As IProgress(Of Long)) As Task

Se um FindFilesAsync método retornar uma lista de todos os arquivos que atendem a um padrão de pesquisa específico, o retorno de chamada de progresso poderá fornecer uma estimativa do percentual de trabalho concluído e o conjunto atual de resultados parciais.If a FindFilesAsync method returns a list of all files that meet a particular search pattern, the progress callback could provide an estimate of the percentage of work completed and the current set of partial results. Ele pode fornecer essas informações com uma tupla:It could provide this information with either a tuple:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
            string pattern,
            IProgress<Tuple<double,
            ReadOnlyCollection<List<FileInfo>>>> progress)
Public Function FindFilesAsync(pattern As String,
                               progress As IProgress(Of Tuple(Of Double, ReadOnlyCollection(Of List(Of FileInfo))))) _
                               As Task(Of ReadOnlyCollection(Of FileInfo))

ou com um tipo de dados que é específico para a API:or with a data type that's specific to the API:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
    string pattern,
    IProgress<FindFilesProgressInfo> progress)
Public Function FindFilesAsync(pattern As String,
                               progress As IProgress(Of FindFilesProgressInfo)) _
                               As Task(Of ReadOnlyCollection(Of FileInfo))

No último caso, o tipo de dados especial geralmente é sufixado com ProgressInfo.In the latter case, the special data type is usually suffixed with ProgressInfo.

Se as implementações de toque fornecem sobrecargas que aceitam um progress parâmetro, elas devem permitir que o argumento seja null , caso em que nenhum progresso é relatado.If TAP implementations provide overloads that accept a progress parameter, they must allow the argument to be null, in which case no progress is reported. As implementações do TAP devem relatar o progresso ao Progress<T> objeto de forma síncrona, o que permite que o método assíncrono forneça rapidamente o progresso.TAP implementations should report the progress to the Progress<T> object synchronously, which enables the asynchronous method to quickly provide progress. Ele também permite que o consumidor do progresso determine como e onde melhor lidar com as informações.It also allows the consumer of the progress to determine how and where best to handle the information. Por exemplo, a instância de progresso poderia optar por controlar retornos de chamada e gerar eventos em um contexto de sincronização capturado.For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

<T>Implementações de IProgressIProgress<T> implementations

O .NET fornece a Progress<T> classe, que implementa IProgress<T> ..NET provides the Progress<T> class, which implements IProgress<T>. A classe Progress<T> é declarada da seguinte forma:The Progress<T> class is declared as follows:

public class Progress<T> : IProgress<T>  
{  
    public Progress();  
    public Progress(Action<T> handler);  
    protected virtual void OnReport(T value);  
    public event EventHandler<T>? ProgressChanged;  
}  

Uma instância de Progress<T> expõe um evento ProgressChanged, o qual é gerado sempre que a operação assíncrona relata uma atualização de progresso.An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. O evento ProgressChanged é gerado no objeto de SynchronizationContext que foi capturado quando a instância de Progress<T> foi criada.The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. Se não havia contexto de sincronização disponível, um contexto padrão que tem como alvo o pool de segmentos é usado.If no synchronization context was available, a default context that targets the thread pool is used. É possível registrar manipuladores com esse evento.Handlers may be registered with this event. Um único manipulador também pode ser fornecido para o construtor Progress<T> para maior conveniência. Seu comportamento é exatamente como um manipulador de eventos para o evento ProgressChanged.A single handler may also be provided to the Progress<T> constructor for convenience, and behaves just like an event handler for the ProgressChanged event. As atualizações de progresso são geradas de forma assíncrona para evitar atrasar a operação assíncrona enquanto os manipuladores de eventos são executados.Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. Outra implementação de IProgress<T> pode optar por aplicar uma semântica diferente.Another IProgress<T> implementation could choose to apply different semantics.

Escolhendo as sobrecargas a serem fornecidasChoosing the overloads to provide

Se uma implementação de TAP ambos os parâmetros CancellationToken e IProgress<T> opcionais, ela poderá potencialmente exigir até quatro cargas de trabalho:If a TAP implementation uses both the optional CancellationToken and optional IProgress<T> parameters, it could potentially require up to four overloads:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
public Task MethodNameAsync(…, IProgress<T> progress);
public Task MethodNameAsync(…,
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken cancellationToken) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task
Public MethodNameAsync(…, cancellationToken As CancellationToken,
                       progress As IProgress(Of T)) As Task  

No entanto, muitas implementações de toque não fornecem recursos de cancelamento ou de progresso, portanto, eles exigem um único método:However, many TAP implementations don't provide cancellation or progress capabilities, so they require a single method:

public Task MethodNameAsync(…);  
Public MethodNameAsync(…) As Task  

Se uma implementação de TAP oferecer suporte a cancelamento ou progresso, mas não a ambos, ela poderá fornecer duas sobrecargas:If a TAP implementation supports either cancellation or progress but not both, it may provide two overloads:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
  
// … or …  
  
public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken) As Task  
  
' … or …  
  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task  

Se uma implementação de TAP oferecer suporte a cancelamento e progresso, ela poderá expor todas as quatro sobrecargas.If a TAP implementation supports both cancellation and progress, it may expose all four overloads. No entanto, ela pode fornecer somente estas duas:However, it may provide only the following two:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…,
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken,
                       progress As IProgress(Of T)) As Task  

Para compensar as duas combinações intermediárias ausentes, os desenvolvedores podem passar None ou um CancellationToken padrão para o parâmetro cancellationToken e null para o parâmetro progress.To compensate for the two missing intermediate combinations, developers may pass None or a default CancellationToken for the cancellationToken parameter and null for the progress parameter.

Se você esperar que cada uso do método TAP ofereça suporte ao cancelamento ou ao progresso, poderá omitir as sobrecargas que não aceitam o parâmetro relevante.If you expect every usage of the TAP method to support cancellation or progress, you may omit the overloads that don't accept the relevant parameter.

Se você decidir expor várias sobrecargas para tornar o cancelamento ou o progresso opcional, as sobrecargas que não suportam o cancelamento ou o progresso devem se comportar como se estivessem None para cancelamento ou null para o progresso para a sobrecarga que oferece suporte a esses.If you decide to expose multiple overloads to make cancellation or progress optional, the overloads that don't support cancellation or progress should behave as if they passed None for cancellation or null for progress to the overload that does support these.

TítuloTitle DESCRIÇÃODescription
Padrões de programação assíncronaAsynchronous Programming Patterns Apresenta os três padrões para execução de operações assíncronas: TAP (Padrão Assíncrono Baseado em Tarefas), APM (Modelo de Programação Assíncrona) e EAP (Padrão Assíncrono Baseado em Eventos).Introduces the three patterns for performing asynchronous operations: the Task-based Asynchronous Pattern (TAP), the Asynchronous Programming Model (APM), and the Event-based Asynchronous Pattern (EAP).
Implementando o padrão assíncrono baseado em tarefaImplementing the Task-based Asynchronous Pattern Descreve como implementar o TAP de três formas: usando os compiladores C# e Visual Basic no Visual Studio, manualmente ou por meio de uma combinação de compilador com o método manual.Describes how to implement the Task-based Asynchronous Pattern (TAP) in three ways: by using the C# and Visual Basic compilers in Visual Studio, manually, or through a combination of the compiler and manual methods.
Consumindo o padrão assíncrono baseado em tarefaConsuming the Task-based Asynchronous Pattern Descreve como você pode usar tarefas e retornos de chamada para implementar a espera sem causar bloqueios.Describes how you can use tasks and callbacks to achieve waiting without blocking.
Interoperabilidade com outros tipos e padrões assíncronosInterop with Other Asynchronous Patterns and Types Descreve como usar o TAP (Padrão Assíncrono Baseado em Tarefas) para implementar o APM (Modelo de Programação Assíncrona) e o EAP (Padrão Assíncrono Baseado em Eventos).Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).