Modelo asincrónico basado en tareas (TAP)Task-based asynchronous pattern (TAP)

El patrón asincrónico basado en tareas (TAP) se basa en los tipos System.Threading.Tasks.Task y System.Threading.Tasks.Task<TResult> del espacio de nombres System.Threading.Tasks, que se usan para representar operaciones asincrónicas arbitrarias.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. TAP es el patrón asincrónico de diseño recomendado para los nuevos desarrollos.TAP is the recommended asynchronous design pattern for new development.

Nombres, parámetros y tipos de valores devueltosNaming, parameters, and return types

TAP usa un solo método para representar el inicio y la finalización de una operación asincrónica.TAP uses a single method to represent the initiation and completion of an asynchronous operation. Esto contrasta con el modelo de programación asincrónico (APM o IAsyncResult) y con el modelo asincrónico basado en eventos (EAP).This contrasts with both the Asynchronous Programming Model (APM or IAsyncResult) pattern and the Event-based Asynchronous Pattern (EAP). APM requiere los métodos Begin y End.APM requires Begin and End methods. EPA requiere un método con el sufijo Async y también requiere uno o más eventos, tipos de delegado de controlador de eventos y 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. Los métodos asincrónicos en TAP incluyen el sufijo Async después del nombre de la operación para los métodos que devuelven tipos que admiten await, como Task, Task<TResult>, ValueTask y 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 ejemplo, una operación Get asincrónica que devuelve un Task<String> se puede denominar GetAsync.For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync. Si va a agregar un método de TAP a una clase que ya contiene un nombre de método EAP con el sufijo Async, use el sufijo TaskAsync en su lugar.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 ejemplo, si la clase ya tiene un método GetAsync, use el nombre GetTaskAsync.For example, if the class already has a GetAsync method, use the name GetTaskAsync. Si un método inicia una operación asincrónica pero no devuelve un tipo que admite await, su nombre debe comenzar por Begin, Start u otro verbo que sugiera que este método no devuelve ni genera el resultado de la operación.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.  

Un método de TAP devuelve System.Threading.Tasks.Task o System.Threading.Tasks.Task<TResult>, en función de si el método sincrónico correspondiente devuelve void o un 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.

Los parámetros de un método de TAP deben coincidir con los parámetros de su homólogo sincrónico y se deben proporcionar en el mismo orden.The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. Sin embargo, los parámetros out y ref están exentos de esta regla y se deben evitar completamente.However, out and ref parameters are exempt from this rule and should be avoided entirely. En su lugar, los datos que se hubieran devuelto con un parámetro out o ref se deben devolver como parte del tipo TResult devuelto por Task<TResult> y deben usar una tupla o una estructura de datos personalizada para incluir varios 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. También debería considerar agregar un parámetro CancellationToken incluso si el homólogo sincrónico del método TAP no ofrece ninguno.You should also consider adding a CancellationToken parameter even if the TAP method's synchronous counterpart does not offer one.

Los métodos que están dedicados exclusivamente a la creación, manipulación o combinación de tareas (donde el intento asincrónico del método está claro en el nombre del método o en el nombre del tipo al que el método pertenece) no necesitan seguir este modelo de nomenclatura; esos métodos se conocen a menudo como combinadores (también denominados elementos de combinación).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. Los ejemplos de combinadores incluyen WhenAll y WhenAny, y se describen en la sección que describe los combinadores integrados basados en tareas titulada Usar los combinadores integrados basados en tareas del artículo Utilizar el modelo asincrónico basado en tareas.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 obtener ejemplos de cómo la sintaxis de TAP difiere de la sintaxis empleada en patrones heredados de programación asincrónica como el modelo de programación asincrónica (APM) y el patrón asincrónico basado en eventos (EAP), vea Modelos para la programación asincrónica.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.

Inicio de una operación asincrónicaInitiating an asynchronous operation

Un método asincrónico basado en TAP puede hacer una pequeña cantidad de trabajo sincrónicamente, como validar argumentos e iniciar la operación asincrónica, antes de que devuelva la tarea 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. El trabajo sincrónico debe reducirse al mínimo de modo que el método asincrónico pueda volver rápidamente.Synchronous work should be kept to the minimum so the asynchronous method can return quickly. Entre las razones para un retorno rápido se incluyen las siguientes:Reasons for a quick return include the following:

  • Los métodos asincrónicos se pueden invocar desde subprocesos de la interfaz de usuario (UI) y cualquier trabajo sincrónico de ejecución prolongada puede dañar la capacidad de respuesta de la aplicación.Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • Se pueden iniciar varios métodos asincrónicos simultáneamente.Multiple asynchronous methods may be launched concurrently. Por tanto, cualquier trabajo de ejecución prolongada en la parte sincrónica de un método asincrónico puede retrasar el inicio de otras operaciones asincrónicas, lo que reduce las ventajas de la simultaneidad.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.

En algunos casos, la cantidad de trabajo necesario para completar la operación es menor que la cantidad de trabajo necesario para iniciar la operación de forma asincrónica.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. La lectura de una secuencia donde la operación de lectura se puede satisfacer mediante datos que ya están almacenados en búfer en la memoria es un ejemplo de este escenario.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. En casos como este, la operación puede completarse sincrónicamente y puede devolver una tarea que ya se ha completado.In such cases, the operation may complete synchronously, and may return a task that has already been completed.

ExcepcionesExceptions

Un método asincrónico debe generar una excepción fuera de la llamada de método asincrónico solo como respuesta a un error 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. Los errores de uso nunca deben producirse en código de producción.Usage errors should never occur in production code. Por ejemplo, si al pasar una referencia nula (Nothing en Visual Basic) como uno de los argumentos del método se produce un estado de error (representado normalmente por una excepción ArgumentNullException), puede modificar el código de llamada para asegurarse de que nunca se pase una referencia nula.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 los demás errores, las excepciones que se producen cuando se ejecuta un método asincrónico deben asignarse a la tarea devuelta, aunque el método asincrónico se complete sincrónicamente antes de que se devuelva la tarea.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, una tarea contiene como máximo una excepción.Typically, a task contains at most one exception. Sin embargo, si la tarea representa varias operaciones (por ejemplo, WhenAll), se pueden asociar varias excepciones a una única tarea.However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

Entorno de destinoTarget environment

Cuando implementa un método de TAP, puede determinar dónde se produce la ejecución asincrónica.When you implement a TAP method, you can determine where asynchronous execution occurs. Puede elegir ejecutar la carga de trabajo en el grupo de subprocesos, implementarla mediante E/S asincrónica (sin enlazarse a un subproceso para la mayor parte de la ejecución de la operación), ejecutarla en un subproceso concreto (como el subproceso de la interfaz de usuario) o usar cualquier número de contextos posibles.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. Un método de TAP incluso puede no tener nada que ejecutar y puede devolver simplemente una clase Task que representa la ocurrencia de una condición en otra ubicación en el sistema (por ejemplo, una tarea que representa datos que llegan a una estructura de datos en cola).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).

El autor de la llamada al método TAP puede bloquear la espera para que el método de TAP se complete mediante la espera sincrónica en la tarea resultante, o bien puede ejecutar código (de continuación) adicional cuando la operación asincrónica se completa.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. El creador del código de continuación tiene control sobre lo que ese código ejecuta.The creator of the continuation code has control over where that code executes. Puede crear el código de continuación explícitamente, mediante métodos de la clase Task (por ejemplo, ContinueWith) o implícitamente, usando la compatibilidad con lenguaje sobre las continuaciones (por ejemplo, await en C#, Await en Visual Basic, AwaitValue en 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#).

Estado de la tareaTask status

La clase Task proporciona un ciclo de vida para las operaciones asincrónicas y ese ciclo se representa mediante la enumeración TaskStatus.The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. Para admitir los casos extremos de tipos que se derivan de Task y Task<TResult>, y para admitir la separación de la construcción de la programación, la clase Task expone un 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. Las tareas creadas por los constructores públicos Task se denominan tareas en frío, porque inician su ciclo de vida en el estado Created no programado y solo se programan cuando se llama a Start en estas instancias.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 las demás tareas inician su ciclo de vida en un estado activo, lo que significa que las operaciones asincrónicas que representan ya se han iniciado y su estado de la tarea es un valor de enumeración distinto 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 las tareas que se devuelven de métodos de TAP deben estar activas.All tasks that are returned from TAP methods must be activated. Si un método de TAP usa internamente el constructor de una tarea para crear instancias de la tarea que se va a devolver, el método de TAP debe llamar a Start en el objeto Task antes de devolverlo.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. Los consumidores de un método de TAP pueden suponer con seguridad que la tarea devuelta está activa y no deben intentar llamar a Start en ningún Task que se devuelve de un método de 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. La llamada a Start en una tarea activa produce una excepción InvalidOperationException.Calling Start on an active task results in an InvalidOperationException exception.

Cancelación (opcional)Cancellation (optional)

En TAP, la cancelación es opcional tanto para los implementadores de método asincrónico como para los consumidores de este método.In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. Si una operación permite la cancelación, expone una sobrecarga del método asincrónico que acepta un token de cancelación (instancia de CancellationToken).If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). Por convención, el parámetro se denomina 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

La operación asincrónica supervisa este token para las solicitudes de cancelación.The asynchronous operation monitors this token for cancellation requests. Si recibe una solicitud de cancelación, puede elegir admitir esa solicitud y cancelar la operación.If it receives a cancellation request, it may choose to honor that request and cancel the operation. Si la solicitud de cancelación hace que el trabajo finalice prematuramente, el método de TAP devuelve una tarea que finaliza en el estado Canceled; no hay ningún resultado disponible y no se produce ninguna excepción.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. El estado Canceled se considera un estado final (completado) para una tarea, junto con los estados Faulted y RanToCompletion.The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. Por tanto, si una tarea está en el estado Canceled, su propiedad IsCompleted devuelve true.Therefore, if a task is in the Canceled state, its IsCompleted property returns true. Cuando una tarea se completa en el estado Canceled, cualquier continuación registrada con la tarea se programa o se ejecuta, a menos que se especificara una opción de continuación como NotOnCanceled para rechazar la continuación.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. Cualquier código que espera de forma asincrónica una tarea cancelada mediante el uso de características del lenguaje sigue ejecutándose pero recibe un objeto OperationCanceledException o una excepción derivada del mismo.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. El código que se bloquea sincrónicamente en espera de la tarea mediante métodos como Wait y WaitAll también continúa ejecutándose con una excepción.Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

Si un token de cancelación ha solicitado la cancelación antes de que se llame al método de TAP que acepta ese token, el método de TAP debe devolver una tarea 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. Sin embargo, si se solicita la cancelación mientras la operación asincrónica se ejecuta, la operación asincrónica no necesita aceptar la solicitud de cancelación.However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. La tarea devuelta debe finalizar en el estado Canceled solo si la operación termina como resultado de la solicitud de cancelación.The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. Si se solicita la cancelación pero aún se produce un resultado o una excepción, la tarea debe finalizar en el estado RanToCompletion o 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 los métodos asincrónicos que desean exponer la capacidad de cancelarse ante todo, no tiene que proporcionar una sobrecarga que no acepte un token de cancelación.For asynchronous methods that want to expose the ability to be cancelled first and foremost, you don't have to provide an overload that doesn’t accept a cancellation token. Para los métodos que no pueden cancelarse, no proporcione sobrecargas que acepten un token de cancelación; esto ayuda a indicar al llamador si el método de destino es realmente cancelable.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. El código de consumidor que no desea la cancelación puede llamar a un método que acepta un objeto CancellationToken y proporciona None como valor del argumento.Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None es funcionalmente equivalente al objeto CancellationToken predeterminado.None is functionally equivalent to the default CancellationToken.

Informe de progreso (opcional)Progress reporting (optional)

Algunas operaciones asincrónicas se benefician de proporcionar notificaciones de progreso; se suelen usar para actualizar una interfaz de usuario con información sobre el progreso de la operación asincrónica.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.

En TAP, el progreso se controla a través de una interfaz IProgress<T>, la cual se pasa al método asincrónico como un parámetro normalmente denominado 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. Proporcionar la interfaz de progreso cuando se llama al método asincrónico ayuda a eliminar condiciones de carrera resultantes de un uso incorrecto (es decir, cuando los controladores de eventos registrados incorrectamente después del inicio de la operación pueden perder actualizaciones).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). Lo que es más importante, la interfaz de progreso admite implementaciones diferentes de progreso, según determina el código usado.More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. Por ejemplo, el código usado puede que desee encargarse solo de la última actualización de progreso, almacenar en búfer todas las actualizaciones, invocar una acción para cada actualización o controlar si se serializa la invocación en un subproceso determinado.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 estas opciones se pueden lograr utilizando otra implementación de la interfaz, personalizada según las necesidades particulares del consumidor.All these options may be achieved by using a different implementation of the interface, customized to the particular consumer’s needs. Como ocurre con la cancelación, las implementaciones de TAP deben proporcionar un parámetro IProgress<T> solo si la API admite notificaciones de progreso.As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

Por ejemplo, si el método ReadAsync anteriormente mencionado en este artículo puede informar del progreso intermedio en forma de número de bytes leídos hasta el momento, la devolución de llamada de progreso puede ser una interfaz 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 

Si un método FindFilesAsync devuelve una lista de todos los archivos que satisfacen un patrón particular de búsqueda, la devolución de progreso puede proporcionar una estimación del porcentaje de trabajo completado así como el conjunto de resultados parciales.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 as well as the current set of partial results. Puede hacerlo con una tupla:It could do this either with 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))

o con un tipo de datos que es específico de la API:or with a data type that is 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))

En este último caso, el tipo de datos especial suele tener el sufijo ProgressInfo.In the latter case, the special data type is usually suffixed with ProgressInfo.

Si las implementaciones de TAP proporcionan sobrecargas que aceptan un parámetro progress, deben permitir que el argumento sea null, en cuyo caso no se notifica ningún progreso.If TAP implementations provide overloads that accept a progress parameter, they must allow the argument to be null, in which case no progress will be reported. Las implementaciones de TAP deben notificar el progreso al objeto Progress<T> sincrónicamente, lo cual permite al método asincrónico proporcionar rápidamente el progreso y hacer que el consumidor de este determine cómo y dónde es mejor controlar la información.TAP implementations should report the progress to the Progress<T> object synchronously, which enables the asynchronous method to quickly provide progress, and allow the consumer of the progress to determine how and where best to handle the information. Por ejemplo, la instancia de progreso puede optar por hacerse con las devoluciones de llamada y generar eventos en un contexto capturado de sincronización.For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

Implementaciones de IProgress<T>IProgress<T> implementations

.NET Framework 4.5.NET Framework 4.5 proporciona una única implementación de IProgress<T>: Progress<T>.The .NET Framework 4.5.NET Framework 4.5 provides a single IProgress<T> implementation: Progress<T>. La clase Progress<T> se declara de la forma siguiente: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;  
}  
Public Class Progress(Of T) : Inherits IProgress(Of T)  
    Public Sub New()  
    Public Sub New(handler As Action(Of T))  
    Protected Overridable Sub OnReport(value As T)  
    Public Event ProgressChanged As EventHandler(Of T>  
End Class  

Una instancia de Progress<T> expone un evento ProgressChanged, que se provoca cada vez que la operación asincrónica informe de una actualización de progreso.An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. El evento ProgressChanged se genera en el objeto SynchronizationContext que se capturó cuando se creó la instancia de Progress<T>.The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. Si no había ningún contexto de sincronización disponible, se usa un contexto predeterminado destinado al grupo de subprocesos.If no synchronization context was available, a default context that targets the thread pool is used. Los controladores pueden registrarse con este evento.Handlers may be registered with this event. También se puede proporcionar un único controlador al constructor Progress<T> por comodidad, y se comportará como un controlador de eventos para el 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. Las actualizaciones de progreso se generan de forma asincrónica para evitar retrasar la operación asincrónica mientras los controladores de eventos se ejecutan.Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. Otra implementación IProgress<T> podría elegir aplicar semánticas diferentes.Another IProgress<T> implementation could choose to apply different semantics.

Elección de las sobrecargas que se van a proporcionarChoosing the overloads to provide

Si una implementación TAP usa la propiedad CancellationToken y los parámetros IProgress<T> opcionales, podría requerir hasta cuatro sobrecargas: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  

Sin embargo, muchas implementaciones TAP no proporcionan ni la cancelación ni las capacidades de progreso, por lo que requieren un único método:However, many TAP implementations provide neither cancellation or progress capabilities, so they require a single method:

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

Si una implementación de TAP admite la cancelación o el progreso pero no ambos, puede proporcionar dos 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  

Si una implementación TAP admite la cancelación y el progreso, puede exponer las cuatro sobrecargas.If a TAP implementation supports both cancellation and progress, it may expose all four overloads. Sin embargo, puede proporcionar solo las dos siguientes: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 las dos combinaciones intermedias que faltan, los desarrolladores pueden pasar la propiedad None o un objeto CancellationToken predeterminado para el parámetro cancellationToken y null para el 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.

Si se espera que cada uso del método TAP admita cancelación o progreso, puede omitir las sobrecargas que no acepten el parámetro pertinente.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.

Si se decide exponer varias sobrecargas para conseguir que la cancelación o el progreso sean opcionales, las sobrecargas que no admitan cancelación o progreso deben comportarse como si pasaran None para la cancelación o null para el progreso en la sobrecarga que admite ambas.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.

TitleTitle DescripciónDescription
Patrones para la programación asincrónicaAsynchronous Programming Patterns Presenta los tres patrones para realizar las operaciones asincrónicas: el patrón asincrónico basado en tareas (TAP), el modelo de programación asincrónica (APM) y el patrón asincrónico basado en eventos (EAP).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).
Implementar el modelo asincrónico basado en tareasImplementing the Task-based Asynchronous Pattern Describe cómo implementar el patrón asincrónico basado en tareas (TAP) de tres maneras: mediante los compiladores de C# y Visual Basic de Visual Studio, manualmente o a través de una combinación del compilador y de métodos manuales.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.
Consuming the Task-based Asynchronous PatternConsuming the Task-based Asynchronous Pattern Describe cómo se pueden utilizar las tareas y las devoluciones de llamada para conseguir esperas sin bloqueos.Describes how you can use tasks and callbacks to achieve waiting without blocking.
Interoperabilidad con otros tipos y patrones asincrónicosInterop with Other Asynchronous Patterns and Types Describe cómo usar el patrón asincrónico basado en tareas (TAP) para implementar el modelo de programación asincrónica (APM) y el patrón asincrónico basado en eventos (EAP).Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).