Modello asincrono basato su attività (TAP)Task-based Asynchronous Pattern (TAP)

Il modello asincrono basato su attività (TAP) è basato sui tipi System.Threading.Tasks.Task e System.Threading.Tasks.Task<TResult> nello spazio dei nomi System.Threading.Tasks, che vengono usati per rappresentare le operazioni asincrone arbitrarie.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 è il modello di progettazione asincrono consigliato per le nuove attività di sviluppo.TAP is the recommended asynchronous design pattern for new development.

Denominazione, parametri e tipi restituitiNaming, Parameters, and Return Types

TAP usa un singolo metodo per rappresentare l'inizio e il completamento di un'operazione asincrona.TAP uses a single method to represent the initiation and completion of an asynchronous operation. Ciò si differenzia dal modello di programmazione asincrono (APM o IAsyncResult), che richiede i metodi Begin e End, nonché dal modello asincrono basato su eventi (EAP), che richiede un metodo con il suffisso Async e inoltre uno o più eventi, tipi delegati del gestore eventi e tipi derivati da EventArg.This is in contrast to the Asynchronous Programming Model (APM or IAsyncResult) pattern, which requires Begin and End methods, and in contrast to the Event-based Asynchronous Pattern (EAP), which requires a method that has the Async suffix and also requires one or more events, event handler delegate types, and EventArg-derived types. I metodi asincroni in TAP includono il suffisso Async dopo il nome dell'operazione. Ad esempio, GetAsync per un'operazione Get.Asynchronous methods in TAP include the Async suffix after the operation name; for example, GetAsync for a Get operation. Se si aggiunge un metodo TAP a una classe che contiene già il nome di un metodo con il suffisso Async, usare invece il suffisso TaskAsync.If you're adding a TAP method to a class that already contains that method name with the Async suffix, use the suffix TaskAsync instead. Ad esempio, se la classe dispone già di un metodo GetAsync, usare il nome GetTaskAsync.For example, if the class already has a GetAsync method, use the name GetTaskAsync.

Un metodo TAP restituisce System.Threading.Tasks.Task o System.Threading.Tasks.Task<TResult>, a seconda che il metodo sincrono corrispondente restituisca 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.

I parametri di un metodo TAP devono corrispondere ai parametri della relativa controparte sincrona e devono essere forniti nello stesso ordine.The parameters of a TAP method should match the parameters of its synchronous counterpart, and should be provided in the same order. Tuttavia, i parametri out e ref sono esclusi da questa regola e dovrebbero essere evitati completamente.However, out and ref parameters are exempt from this rule and should be avoided entirely. Tutti i dati che dovrebbero venire restituiti da un parametro out o ref dovranno invece essere restituiti come parte di TResult restituito da Task<TResult> e usare una tupla o una struttura dei dati personalizzata per contenere più valori.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.

I metodi dedicati esclusivamente alla creazione, modifica o combinazione di attività (dove l'intento asincrono del metodo risulta chiaro nel nome del metodo o nel nome del tipo a cui appartiene il metodo) non devono seguire questo modello di denominazione. Tali metodi vengono spesso definiti combinatori.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. Esempi di combinatori includono WhenAll e WhenAny e sono illustrati nella sezione Utilizzo di combinatori incorporati basati su attività dell'articolo Utilizzo del modello asincrono basato su attività.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.

Per esempi relativi alle differenze di sintassi di TAP rispetto ai modelli di programmazione asincrona legacy, come il modello di programmazione asincrono (APM) e il modello asincrono basato su eventi (EAP), vedere Modelli di programmazione asincrona.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.

Avvio di un'operazione asincronaInitiating an Asynchronous Operation

Un metodo asincrono basato su TAP può eseguire una piccola quantità di lavoro in modo sincrono, ad esempio convalidare gli argomenti e avviare l'operazione asincrona, prima di restituire l'attività risultante.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. Le attività sincrone devono essere minime in modo che il metodo asincrono possa eseguire rapidamente la restituzione.Synchronous work should be kept to the minimum so the asynchronous method can return quickly. I motivi per una restituzione rapida includono:Reasons for a quick return include the following:

  • I metodi asincroni possono essere richiamati dai thread dell'interfaccia utente e le attività sincrone a esecuzione prolungata potrebbero compromettere la velocità di risposta dell'applicazione.Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • Più metodi asincroni possono essere avviati simultaneamente.Multiple asynchronous methods may be launched concurrently. Pertanto, le attività a esecuzione prolungata nella parte sincrona di un metodo asincrono possono ritardare l'avvio di altre operazioni asincrone, riducendo quindi i vantaggi della concorrenza.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.

In alcuni casi, la quantità di lavoro richiesta per completare l'operazione è inferiore alla quantità di lavoro richiesta per avviare un'operazione in modo asincrono.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 lettura da un flusso in cui l'operazione di lettura può essere soddisfatta dai dati che sono già stati memorizzati nel buffer in memoria è un esempio di tale scenario.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. In tali casi, l'operazione può essere completata in modo sincrono e può restituire un'attività già completata.In such cases, the operation may complete synchronously, and may return a task that has already been completed.

EccezioniExceptions

Un metodo asincrono dovrebbe generare un'eccezione utilizzabile da una chiamata al metodo asincrono solo in risposta a un errore di utilizzo.An asynchronous method should raise an exception to be thrown out of the asynchronous method call only in response to a usage error. Gli errori di utilizzo non devono mai verificarsi nel codice di produzione.Usage errors should never occur in production code. Ad esempio, se passando un riferimento Null (Nothing in Visual Basic) come uno degli argomenti del metodo si determina uno stato di errore (generalmente rappresentato da un'eccezione ArgumentNullException), è possibile modificare il codice chiamante per assicurarsi che un riferimento Null non venga mai passato.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. Per tutti gli altri errori, le eccezioni che si verificano quando un metodo asincrono è in esecuzione devono essere assegnate all'attività restituita, anche se il metodo asincrono viene completato in modo sincrono prima che l'attività venga restituita.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. In genere, un'attività contiene al massimo un'eccezione.Typically, a task contains at most one exception. Tuttavia, se l'attività rappresenta più operazioni, (ad esempio WhenAll), più eccezioni possono essere associate a una singola attività.However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

Ambiente di destinazioneTarget Environment

Quando si implementa un metodo TAP, è possibile determinare quando si verifica l'esecuzione asincrona.When you implement a TAP method, you can determine where asynchronous execution occurs. È possibile scegliere di eseguire il carico di lavoro nel pool di thread, implementarlo mediante I/O asincrono (senza associazione a un thread per la maggior parte dell'esecuzione delle operazioni), eseguirlo in un thread specifico (come il thread UI) o usare il numero desiderato di contesti potenziali.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 metodo TAP può anche non avere alcun elemento da eseguire e restituire solo un Task che rappresenta l'occorrenza di una condizione in un'altra posizione nel sistema (ad esempio, un'attività che rappresenta i dati provenienti da una struttura di dati in coda).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).

Il chiamante del metodo TAP può smettere di attendere il completamento del metodo TAP rimanendo in attesa in modalità sincrona dell'attività risultante o potrebbe eseguire codice aggiuntivo (continuazione) al completamento dell'operazione asincrona.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. L'autore del codice di continuazione è in grado di controllare dove viene eseguito il codice.The creator of the continuation code has control over where that code executes. È possibile creare il codice di continuazione in modo esplicito, con i metodi della classe Task, (ad esempio ContinueWith), o in modo implicito, usando il supporto linguistico compilato sulla base delle continuazioni, (ad esempio await in C#, Await in Visual Basic, AwaitValue in 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#).

Stato dell'attivitàTask Status

La classe Task fornisce un ciclo di vita per le operazioni asincrone e il ciclo è rappresentato dall'enumerazione TaskStatus.The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. Per supportare i casi estremi di tipi che derivano da Task e da Task<TResult> e per supportare la separazione della costruzione dalla pianificazione, la classe Task espone un metodo 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. Le attività create dai costruttori Task pubblici vengono definite attività inattive, poiché iniziano il ciclo di vita nello stato non pianificato Created e vengono pianificate solo quando Start viene chiamato su queste istanze.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.

Tutte le altre attività iniziano il ciclo di vita in uno stato attivo, ovvero le operazioni asincrone che rappresentano sono già state avviate e lo stato dell'attività è un valore di enumerazione diverso da 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. Tutte le attività che vengono restituite dai metodi TAP devono essere attivate.All tasks that are returned from TAP methods must be activated. Se un metodo TAP usa internamente il costruttore di un'attività per creare un'istanza dell'attività da restituire, tale metodo deve chiamare Start sull'oggetto Task prima della restituzione.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. I consumer di un metodo TAP possono presumere in modo sicuro che l'attività restituita sia attiva e non devono tentare di chiamare Start su alcun oggetto Task restituito da un metodo 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. Se si chiama Start su un'attività attiva, viene generata un'eccezione InvalidOperationException.Calling Start on an active task results in an InvalidOperationException exception.

Annullamento (facoltativo)Cancellation (Optional)

In TAP, l'annullamento è facoltativo sia per gli implementatori di metodi asincroni che i consumer di metodi asincroni.In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. Se un'operazione consente l'annullamento, espone un overload del metodo asincrono che accetta un token di annullamento (istanza diCancellationToken).If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). Convenzionalmente, al parametro viene assegnato il nome 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

L'operazione asincrona esamina questo token per le richieste di annullamento.The asynchronous operation monitors this token for cancellation requests. Se riceve una richiesta di annullamento, può scegliere di soddisfarla e annullare l'operazione.If it receives a cancellation request, it may choose to honor that request and cancel the operation. Se la richiesta di annullamento determina la fine anticipata del lavoro, il metodo TAP restituisce un'attività che termina nello stato Canceled; non esiste alcun risultato disponibile e non viene generata alcuna eccezione.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. Lo stato Canceled è considerato uno stato finale (o completato) per un task, insieme a Faulted e RanToCompletion.The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. Pertanto, se un'attività è nello stato Canceled, la proprietà IsCompleted restituisce true.Therefore, if a task is in the Canceled state, its IsCompleted property returns true. Quando un'attività viene completata nello stato Canceled, tutte le continuazioni registrate con l'attività vengono pianificate o eseguite, a meno che sia stata specificata un'opzione di continuazione come NotOnCanceled per escludere la continuazione.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. Qualsiasi codice in attesa in modo asincrono di un'attività annullata tramite l'utilizzo di funzionalità del linguaggio continua a essere eseguito ma riceve OperationCanceledException o un'eccezione derivata.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. Il codice bloccato in attesa in modo sincrono dell'attività tramite metodi come Wait e WaitAll continua anch'esso ad essere eseguito con un'eccezione.Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

Se un token di annullamento ha richiesto l'annullamento prima che venga chiamato il metodo TAP che accetta il token, il metodo TAP deve restituire un'attività 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. Tuttavia, se viene richiesto l'annullamento mentre l'operazione asincrona è in esecuzione, tale operazione non ha bisogno di accettare la richiesta di annullamento.However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. L'attività restituita deve terminare nello stato Canceled solo se l'operazione termina come risultato della richiesta di annullamento.The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. Se viene richiesto l'annullamento ma viene comunque prodotto un risultato o un'eccezione, l'attività deve terminare nello stato 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.

Per i metodi asincroni per i quali si vuole esporre la possibilità di annullarli, non si deve specificare un overload che non accetta un token di annullamento.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. Per i metodi che non possono essere annullati, non fornire gli overload che accettano un token di annullamento; ciò indica al chiamante se il metodo di destinazione è realmente annullabile.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. Il codice del consumer che non richiede l'annullamento può chiamare un metodo che accetta CancellationToken e fornisce None come valore dell'argomento.Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None è equivalente dal punto di vista funzionale all'oggetto predefinito CancellationToken.None is functionally equivalent to the default CancellationToken.

Creazione di rapporti sullo stato di avanzamento (facoltativo)Progress Reporting (Optional)

Alcune operazioni asincrone prevedono il vantaggio dell'invio di notifiche sullo stato di avanzamento; queste vengono in genere usate per aggiornare un'interfaccia utente con informazioni sullo stato di avanzamento dell'operazione asincrona.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.

In TAP, lo stato di avanzamento viene gestito mediante un'interfaccia IProgress<T>, che viene passata al metodo asincrono come un parametro in genere denominato 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. La fornitura dell'interfaccia dello stato di avanzamento quando viene chiamato il metodo asincrono consente di eliminare le race condition che derivano da un utilizzo non corretto (ovvero quando gestori eventi non registrati correttamente dopo l'inizio delle operazioni possono non rilevare gli aggiornamenti).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). Ancora più importante, l'interfaccia dello stato di avanzamento supporta varie implementazioni dello stato di avanzamento, in base a quanto determinato dal codice consumer.More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. Ad esempio, il codice consumer potrebbe controllare solo l'ultimo aggiornamento dello stato di avanzamento o memorizzare nel buffer tutti gli aggiornamenti o ancora richiamare un'azione per ogni aggiornamento oppure verificare che venga effettuato il marshalling della chiamata a un particolare thread.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. Tutte queste opzioni possono essere realizzate tramite un'implementazione diversa dell'interfaccia, personalizzata in base ai specifici requisiti del consumer.All these options may be achieved by using a different implementation of the interface, customized to the particular consumer’s needs. Come per l'annullamento, le implementazioni TAP devono fornire un parametro IProgress<T> solo se l'API supporta le notifiche dello stato di avanzamento.As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

Ad esempio, se il metodo ReadAsync illustrato in precedenza in questo articolo può segnalare lo stato di avanzamento intermedio sotto forma di numero di byte letti fino a qual momento, il callback dello stato di avanzamento può essere un'interfaccia 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 un metodo FindFilesAsync restituisce un elenco di tutti i file che soddisfano un criterio di ricerca particolare, il callback dello stato di avanzamento può fornire una stima della percentuale di lavoro completato e il set corrente di risultati parziali.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. A tale scopo è possibile usare 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))

Oppure un tipo di dati specifico dell'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))

Nel secondo caso, il tipo di dati speciale in genere presenta il suffisso ProgressInfo.In the latter case, the special data type is usually suffixed with ProgressInfo.

Se le implementazioni TAP forniscono overload che accettano un parametro progress, devono consentire che l'argomento sia null, nel qual caso non verrà segnalato alcuno stato di avanzamento.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. Le implementazioni TAP devono segnalare lo stato di avanzamento all'oggetto Progress<T> in modo sincrono, in modo che il metodo asincrono possa fornire rapidamente lo stato di avanzamento e il consumer dello stato di avanzamento possa determinare il miglior modo per gestire le informazioni.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. Ad esempio, l'istanza dello stato di avanzamento può scegliere di effettuare il marshalling dei callback e generare eventi in un contesto di sincronizzazione acquisito.For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

Implementazioni di IProgress<T>IProgress<T> Implementations

.NET Framework 4.5.NET Framework 4.5 fornisce un'unica implementazione IProgress<T>: Progress<T>.The .NET Framework 4.5.NET Framework 4.5 provides a single IProgress<T> implementation: Progress<T>. La classe Progress<T> viene dichiarata nel modo seguente: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  

Un'istanza di Progress<T> espone un evento ProgressChanged, che viene generato ogni volta che l'operazione asincrona segnala un aggiornamento di stato.An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. L'evento ProgressChanged viene generato sull'oggetto SynchronizationContext acquisito quando è stata creata l'istanza di Progress<T>.The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. Se non è disponibile alcun contesto di sincronizzazione, viene usato un contesto predefinito destinato al pool di thread.If no synchronization context was available, a default context that targets the thread pool is used. Gestori possono essere registrati con questo evento.Handlers may be registered with this event. Un singolo gestore può inoltre essere fornito al costruttore Progress<T> per praticità, comportandosi esattamente come un gestore per l'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. Gli aggiornamenti dello stato di avanzamento vengono generati in modo asincrono per evitare di ritardare l'operazione asincrona mentre sono in esecuzione i gestori eventi.Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. Un'altra implementazione IProgress<T> può scegliere di applicare semantiche differenti.Another IProgress<T> implementation could choose to apply different semantics.

Scelta degli overload da fornireChoosing the Overloads to Provide

Se un'implementazione TAP usa i parametri facoltativi CancellationToken e IProgress<T>, potrebbe richiedere fino a quattro overload: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  

Tuttavia, molte implementazioni TAP non offrono funzionalità né di annullamento né di segnalazione dello stato di avanzamento, pertanto richiedono un singolo metodo:However, many TAP implementations provide neither cancellation or progress capabilities, so they require a single method:

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

Se l'implementazione TAP supporta l'annullamento o lo stato di avanzamento ma non entrambi, può fornire due overload: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 l'implementazione TAP supporta sia l'annullamento che lo stato di avanzamento, può esporre tutti e quattro gli overload.If a TAP implementation supports both cancellation and progress, it may expose all four overloads. Tuttavia, può fornire solo i seguenti due: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  

Per compensare le due combinazioni intermedie mancanti, gli sviluppatori possono passare None o un oggetto CancellationToken predefinito per il parametro cancellationToken e null per il parametro 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 si prevede che ogni utilizzo del metodo TAP supporti l'annullamento o lo stato di avanzamento, è possibile omettere gli overload che non accettano il parametro 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.

Se si decide di esporre più overload per rendere facoltativi l'annullamento o lo stato di avanzamento, gli overload che non supportano l'annullamento o lo stato di avanzamento devono comportarsi come se passassero None per l'annullamento o null per lo stato di avanzamento all'overload che li supporta.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.

TitoloTitle DescrizioneDescription
Modelli di programmazione asincronaAsynchronous Programming Patterns Vengono illustrati i tre modelli per eseguire le operazioni asincrone: il modello asincrono basato su attività (TAP), il modello di programmazione asincrono (APM) e il modello asincrono basato su eventi (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).
Implementazione del modello asincrono basato su attivitàImplementing the Task-based Asynchronous Pattern Vengono descritti i tre modi per implementare il modello asincrono basato su attività (TAP): tramite i compilatori C# e Visual Basic in Visual Studio, manualmente oppure mediante una combinazione dei primi due.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.
Utilizzo del modello asincrono basato su attivitàConsuming the Task-based Asynchronous Pattern Viene descritto come usare le attività e i callback per ottenere l'attesa senza blocchi.Describes how you can use tasks and callbacks to achieve waiting without blocking.
Interoperabilità con altri tipi e modelli asincroniInterop with Other Asynchronous Patterns and Types Viene descritto come usare il modello asincrono basato su attività (TAP) per implementare il modello di programmazione asincrono (APM) e il modello asincrono basato su eventi (EAP).Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).