Aufgabenbasiertes asynchrones Muster (TAP, Task-based Asynchronous Pattern)Task-based asynchronous pattern (TAP)

Das aufgabenbasierte asynchrone Muster (TAP) basiert auf den Typen System.Threading.Tasks.Task und System.Threading.Tasks.Task<TResult> im System.Threading.Tasks-Namespace, mit denen beliebige asynchrone Vorgänge dargestellt werden.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 ist das empfohlene Entwurfsmuster für asynchrone Neuentwicklungen.TAP is the recommended asynchronous design pattern for new development.

Benennung, Parameter und RückgabetypenNaming, parameters, and return types

TAP verwendet eine einfache Methode, um die Initiierung und den Abschluss eines asynchronen Vorgangs darzustellen.TAP uses a single method to represent the initiation and completion of an asynchronous operation. Dies steht sowohl zum Muster des asynchronen Programmiermodells (Asynchronous Programming Model, APM oder IAsyncResult) als auch dem ereignisbasierten asynchronen Muster (Event-based Asynchronous Pattern, EAP) im Kontrast.This contrasts with both the Asynchronous Programming Model (APM or IAsyncResult) pattern and the Event-based Asynchronous Pattern (EAP). APM erfordert die Methoden Begin und End.APM requires Begin and End methods. EAP erfordert eine Methode, die das Async-Suffix hat, und auch mindestens ein Ereignis, einen Ereignishandler-Delegattypen und aus EventArg abgeleitete Typen.EAP requires a method that has the Async suffix and also requires one or more events, event handler delegate types, and EventArg-derived types. Asynchrone Methoden im TAP umfassen das Suffix Async nach dem Vorgangsnamen für Methoden, die awaitable-Typen zurückgeben, z.B. Task, Task<TResult>, ValueTask und 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>. Ein asynchroner Get-Vorgang, der einen Task<String> zurückgibt, kann z.B. mit GetAsync benannt werden.For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync. Wenn Sie eine TAP-Methode einer Klasse hinzufügen, die bereits eine EAP-Methode mit dem Async-Suffix enthält, verwenden Sie stattdessen das Suffix 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. Wenn beispielsweise die Klasse bereits über eine GetAsync-Methode verfügt, verwenden Sie den Namen GetTaskAsync.For example, if the class already has a GetAsync method, use the name GetTaskAsync. Wenn eine Methode einen asynchronen Vorgang startet, aber keinen awaitable-Typ zurückgibt, sollte ihr Name mit Begin, Start oder einem ähnlichen Verb beginnen, sodass eindeutig ist, dass diese Methode nicht das Ergebnis des Vorgangs zurückgibt.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.  

Die TAP-Methode gibt entweder System.Threading.Tasks.Task oder System.Threading.Tasks.Task<TResult> zurück. Das hängt davon ab, ob die entsprechende synchrone Methode „void“ oder einen TResult-Typ zurückgibt.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.

Die Parameter einer TAP-Methode sollten mit den Parametern der synchronen Entsprechung übereinstimmen und in der gleichen Reihenfolge bereitgestellt werden.The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. Diese Regel gilt jedoch nicht für den out-Parameter und den ref-Parameter. Diese Parameter sollten vollständig vermieden werden.However, out and ref parameters are exempt from this rule and should be avoided entirely. Alle Daten, die über einen out-Parameter oder einen ref-Parameter zurückgegeben werden, sollten stattdessen als Teil des von TResult zurückgegebenen Task<TResult> zurückgegeben werden, wobei für die Verwendung mehrerer Werte ein Tupel oder eine benutzerdefinierte Datenstruktur genutzt wird.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. Sie sollten auch erwägen, einen CancellationToken-Parameter hinzuzufügen, sogar dann, wenn die synchrone Entsprechung der TAP-Methode keinen anbietet.You should also consider adding a CancellationToken parameter even if the TAP method's synchronous counterpart does not offer one.

Methoden, die ausschließlich zur Erstellung, Bearbeitung oder Kombination von Tasks dienen (wobei die asynchrone Verwendung der Methode im Methodennamen oder im Namen des Typs, zu dem die Methode gehört, angegeben wird), müssen nicht nach diesem Benennungsmuster benannt werden. Diese Methoden werden häufig als Combinators bezeichnet.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. Beispiele für Combinators umfassen WhenAll und WhenAny und werden im Abschnitt Verwenden der integrierten taskbasierten Combinators des Artikels Verwenden des taskbasierten asynchronen Musters erläutert.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.

Beispiele dafür, wie die TAP-Syntax sich von der Syntax in Legacyversionen des asynchronen Programmiermusters (beispielsweise dem asynchronen Programmiermodell (kurz APM) und dem ereignisbasierten asynchronen Muster (EAP)) unterscheidet, finden Sie unter Muster für die asynchrone Programmierung.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.

Initiieren eines asynchronen VorgangsInitiating an asynchronous operation

Eine asynchrone Methode, die auf TAP basiert, kann eine kleine Menge an Arbeit synchron ausführen, beispielsweise das Überprüfen von Argumenten und das Initiieren des asynchronen Vorgangs, bevor sie die resultierende Aufgabe zurückgibt.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. Synchrone Arbeiten sollten auf ein Minimum beschränkt werden, damit die asynchrone Methode schnell zurückgeben kann.Synchronous work should be kept to the minimum so the asynchronous method can return quickly. Gründe für eine schnelle Rückgabe umfassen Folgendes:Reasons for a quick return include the following:

  • Asynchrone Methoden können von den Threads der Benutzeroberfläche aufgerufen werden und jede synchrone Arbeit mit langer Laufzeit kann die Reaktionszeit der Anwendung beeinträchtigen.Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • Mehrere asynchrone Methoden können gleichzeitig ausgelöst werden.Multiple asynchronous methods may be launched concurrently. Daher kann jede Arbeit mit langer Laufzeit im synchronen Teil einer asynchronen Methode die Initiierung anderer asynchroner Operationen verzögern und so sie die Vorteile der Nebenläufigkeit verringern.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 einigen Fällen ist der Arbeitsaufwand, der erforderlich ist, um den Vorgang abzuschließen, kleiner als der Arbeitsaufwand, der erforderlich ist, um den Vorgang asynchron zu starten.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. Lesen aus einem Stream, bei dem der Lesevorgang durch Daten erfüllt werden kann, die bereits im Arbeitsspeicher gepuffert werden, ist ein Beispiel für ein solches Szenario.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 solchen Fällen wird der Vorgang möglicherweise synchron abgeschlossen, und eine bereits abgeschlossene Aufgabe kann zurückgegeben werden.In such cases, the operation may complete synchronously, and may return a task that has already been completed.

AusnahmenExceptions

Eine asynchrone Methode sollte nur Ausnahmen auslösen, die aufgrund eines Verwendungsfehlers beim Aufruf der asynchronen Methode ausgelöst werden.An asynchronous method should raise an exception to be thrown out of the asynchronous method call only in response to a usage error. Verwendungsfehler sollten nie im Produktionscode auftreten.Usage errors should never occur in production code. Verursacht beispielsweise die Übergabe eines NULL-Verweises (Nothing in Visual Basic) als eines der Argumente der Methode einen Fehlerzustand (normalerweise dargestellt durch eine ArgumentNullException-Ausnahme), können Sie den Aufrufcode ändern, um sicherzustellen, dass nie ein NULL-Verweis übergeben wird.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. Für alle anderen Fehler sollten Ausnahmen, die beim Ausführen einer asynchronen Methode auftreten, der zurückgegebenen Aufgabe zugewiesen werden. Dies gilt auch dann, wenn die asynchrone Methode zufällig synchron abschließt, bevor die Aufgabe zurückgegeben wird.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 der Regel enthält eine Aufgabe höchstens eine Ausnahme.Typically, a task contains at most one exception. Falls die Aufgabe jedoch mehrere Vorgänge darstellt (beispielsweise bei WhenAll), können einer einzelnen Aufgabe mehrere Ausnahmen zugeordnet werden.However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

ZielumgebungTarget environment

Wenn Sie eine TAP-Methode implementieren, können Sie bestimmen, wo die asynchrone Ausführung auftritt.When you implement a TAP method, you can determine where asynchronous execution occurs. Sie können die Arbeitslast im Threadpool ausführen lassen, sie mithilfe einer asynchronen E/A implementieren (sodass sie für den Großteil der Ausführung des Vorgangs nicht an einen Thread gebunden ist), sie nach Bedarf in einem bestimmten Thread (z. B. dem UI-Thread) oder einer beliebigen Anzahl von anderen potenziellen Kontexten ausführen lassen.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. Es kann sogar vorkommen, dass eine TAP-Methode nichts ausführt und nur einen Task zurückgibt, der das Auftreten einer Bedingung an anderer Stelle im System darstellt (z.B. einen Task, der bei einer Datenstruktur in der Warteschlange eingehende Daten darstellt).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).

Die aufrufende Funktion der TAP-Methode blockiert möglicherweise den Wartevorgang für die TAP-Methode, indem synchron auf den resultierenden Task gewartet wird, oder führt eventuell zusätzlichen (Fortsetzungs-)Code aus, wenn der asynchrone Vorgang abgeschlossen ist.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. Der Ersteller des Fortsetzungscodes steuert, wo dieser Code ausgeführt wird.The creator of the continuation code has control over where that code executes. Sie können diesen Fortsetzungscode entweder explizit durch Methoden der Task-Klasse (z. B. ContinueWith) oder implizit mithilfe von Sprachunterstützung erstellen, die auf Fortsetzungen aufbaut (zum Beispiel 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#).

AufgabenstatusTask status

Die Task-Klasse stellt einen Lebenszyklus für asynchrone Vorgänge bereit, und dieser Zyklus wird durch die TaskStatus-Enumeration dargestellt.The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. Für die Unterstützung von Ausnahmefällen von Typen, die von Task und Task<TResult> abgeleitet werden, sowie für die Unterstützung der Trennung von Erstellung und Planung macht die Task-Klasse eine Start-Methode verfügbar.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. Von den öffentlichen Task-Konstruktoren erstellte Tasks werden als inaktive Tasks bezeichnet, da ihr Lebenszyklus im nicht geplanten Zustand Created beginnt und sie erst im geplanten Zustand sind, wenn Start für diese Instanzen aufgerufen wird.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.

Der Lebenszyklus aller anderen Aufgaben beginnt im aktiven Zustand. Dies bedeutet, dass die asynchronen Vorgänge, die sie darstellen, bereits initiiert wurden, und dass ihr Aufgabenzustand ein anderer Enumerationswert als TaskStatus.Created ist.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. Alle Aufgaben, die von TAP-Methoden zurückgegeben werden, müssen aktiviert sein.All tasks that are returned from TAP methods must be activated. Wenn eine TAP-Methode intern den zurückzugebenden Task mit dem Konstruktor des Tasks instanziiert, muss die TAP-Methode vor dem Zurückgeben des Tasks Start für das Task-Objekt aufrufen.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. Consumer einer TAP-Methode können davon ausgehen, dass die zurückgegebene Aufgabe aktiv ist, und sollten nicht versuchen, Start für einen von einer TAP-Methode zurückgegebenen Task aufzurufen.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. Der Aufruf von Start für eine aktive Aufgabe führt zu einer InvalidOperationException-Ausnahme.Calling Start on an active task results in an InvalidOperationException exception.

Abbruch (optional)Cancellation (optional)

Im TAP ist Abbruch sowohl für Implementierer asynchroner Methoden als auch für Consumer asynchroner Methoden optional.In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. Wenn ein Vorgang einen Abbruch zulässt, macht er eine Überladung der asynchronen Methode verfügbar, die ein Abbruchtoken akzeptiert (CancellationToken-Instanz).If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). Gemäß der Konvention lautet der Name des Parameters 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

Der asynchrone Vorgang überwacht dieses Token auf Abbruchanforderungen.The asynchronous operation monitors this token for cancellation requests. Wenn es eine Abbruchanforderung empfängt, kann es diese Anforderung erfüllen und den Vorgang abbrechen.If it receives a cancellation request, it may choose to honor that request and cancel the operation. Wenn die Abbruchanforderung dazu führt, dass die Arbeit vorzeitig beendet wird, gibt die TAP-Methode eine Aufgabe zurück, die im Canceled-Zustand beendet wird. Es ist kein Ergebnis verfügbar und keine Ausnahme wird ausgelöst.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. Der Zustand Canceled gilt als endgültiger (abgeschlossener) Zustand einer Aufgabe, ebenso wie die Zustände Faulted und RanToCompletion.The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. Wenn eine Aufgabe im Zustand Canceled ist, gibt ihre IsCompleted-Eigenschaft true zurück.Therefore, if a task is in the Canceled state, its IsCompleted property returns true. Wenn eine Aufgabe im Canceled-Zustand abgeschlossen wird, werden alle mit der Aufgabe registrierten Fortsetzungen geplant oder ausgeführt, es sei denn, eine Fortsetzungsmöglichkeit wie NotOnCanceled wurde angegeben, um die Fortsetzung zu beenden.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. Die Ausführung von jedem Code, der mithilfe von Sprachfunktionen asynchron auf eine abgebrochene Aufgabe wartet, wird weiter ausgeführt, aber der Code empfängt eine OperationCanceledException-Ausnahme oder eine von ihr abgeleitete Ausnahme.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. Synchron blockierter Code, der durch Methoden wie Wait und WaitAll auf die Aufgabe wartet, wird ebenso weiter mit einer Ausnahme ausgeführt.Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

Wenn ein Abbruchtoken den Abbruch angefordert hat, bevor die TAP-Methode, die dieses Token akzeptiert, aufgerufen wurde, sollte die TAP-Methode eine Canceled-Aufgabe zurückgeben.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. Wenn jedoch der Abbruch während der Ausführung des asynchronen Vorgangs angefordert wird, muss der asynchrone Vorgang die Abbruchanforderung nicht erfüllen.However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. Die zurückgegebene Aufgabe sollte nur dann im Canceled-Zustand enden, wenn der Vorgang aufgrund einer Abbruchanforderung beendet wird.The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. Wird der Abbruch angefordert aber dennoch ein Ergebnis oder eine Ausnahme erzeugt, sollte die Aufgabe im Zustand RanToCompletion oder Faulted enden.If cancellation is requested but a result or an exception is still produced, the task should end in the RanToCompletion or Faulted state.

Für asynchrone Methoden, bei denen in erster Linie die Funktion zu deren Abbruch verfügbar gemacht werden soll, müssen Sie keine Überladung bereitstellen, die kein Abbruchtoken akzeptiert.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. Für Methoden, die nicht abgebrochen werden können, sollten keine Überladungen bereitgestellt werden, die ein Abbruchstoken akzeptieren. So lässt sich leichter dem Aufrufer mitteilen, ob die Zielmethode tatsächlich abgebrochen werden kann.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. Consumercode, der keinen Abbruch wünscht, wird möglicherweise eine Methode aufrufen, die CancellationToken akzeptiert und None als den Argumentwert bereitstellen.Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None ist zu dem standardmäßigen CancellationToken funktional äquivalent.None is functionally equivalent to the default CancellationToken.

Statusberichterstellung (optional)Progress reporting (optional)

Mehrere asynchrone Vorgänge profitieren von dem Bereitstellen von Statusbenachrichtigungen. Diese werden in der Regel verwendet, um eine Benutzeroberfläche mit Informationen zum Status der asynchronen Operation zu aktualisieren.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 wird der Status wird durch eine IProgress<T>-Schnittstelle behandelt, die der asynchronen Methode als Parameter übergeben wird, der normalerweise progress genannt wird.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. Durch das Bereitstellen der Statusschnittstelle zum Zeitpunkt des Aufrufs der asynchronen Methode lassen sich leichter Racebedingungen vermeiden, die aus falscher Verwendung resultieren (d. h., wenn Ereignishandler, die nach dem Aufruf des Vorgangs nicht ordnungsgemäß registriert wurden, möglicherweise Updates verpassen).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). Vor allem unterstützt die Statusschnittstelle jedoch verschiedene Implementierungen des Status, die durch den verwendeten Code bestimmt werden.More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. Beispielsweise sollte der verwendete Code sich möglicherweise nur für das neueste Statusupdate interessieren oder alle Updates puffern oder eine Aktion für jedes Update aufrufen oder steuern, ob der Aufruf eines bestimmten Thread gemarshallt wird.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. Diese Optionen werden erreicht, indem eine andere Implementierung der Schnittstelle verwendet wird, die an bestimmte Anforderungen des Consumers angepasst wird.All these options may be achieved by using a different implementation of the interface, customized to the particular consumer’s needs. Wie bei einem Abbruch sollten auch TAP-Implementierungen nur dann einen IProgress<T>-Parameter bereitstellen, wenn die API Statusbenachrichtigungen unterstützt.As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

Wenn beispielsweise die weiter oben in diesem Artikel beschriebene ReadAsync-Methode in der Lage ist, einen Zwischenstatus in Form der Anzahl von bisher gelesenen Bytes zu melden, könnte der Statusrückruf eine IProgress<T>-Schnittstelle sein: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 

Wenn eine FindFilesAsync-Methode eine Liste aller Dateien zurückgegeben hat, die einem bestimmten Suchmuster entsprechen, kann der Statusrückruf einen geschätzten Prozentsatz der abgeschlossenen Arbeit sowie den aktuellen Satz von partiellen Ergebnissen bereitstellen.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. Dies kann entweder mit einem Tupel erfolgen: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))

oder mit einem für die API spezifischen Datentyp: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))

In letzterem Fall wird an den speziellen Datentyp für gewöhnlich das Suffix ProgressInfo angefügt werden.In the latter case, the special data type is usually suffixed with ProgressInfo.

Wenn TAP-Implementierungen Überladungen bereitstellen, die einen Statusparameter akzeptieren, müssen sie den Wert progress für das Argument null zulassen. In diesem Fall wird kein Status gemeldet.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. TAP-Implementierungen sollten den Status synchron an das Progress<T>-Objekt melden, das die asynchrone Methode ermöglicht, um den Status schnell bereitzustellen und dem Consumer des Status ermöglichen, zu bestimmen wie und wo die Informationen am besten bearbeitet werden.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. Zum Beispiel kann die Statusinstanz Rückrufe marshallen und Ereignisse auf einem aufgezeichneten Synchronisierungskontext auslösen.For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

IProgress<T>-ImplementierungenIProgress<T> implementations

.NET Framework 4.5 stellt eine einzelne IProgress<T>-Implementierung bereit: Progress<T>.The .NET Framework 4.5 provides a single IProgress<T> implementation: Progress<T>. Die Progress<T>-Klasse wird folgendermaßen deklariert: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  

Eine Instanz von Progress<T> macht ein ProgressChanged-Ereignis verfügbar, das jedes Mal ausgelöst wird, wenn der asynchrone Vorgang ein Statusupdate meldet.An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. Das ProgressChanged-Ereignis wird auf das SynchronizationContext-Objekt ausgelöst, das aufgezeichnet wurde, als die Progress<T>-Instanz instanziiert wurde.The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. Wenn kein Synchronisierungskontext verfügbar war, wird ein Standardkontext, der auf den Threadpool abzielt, verwendet.If no synchronization context was available, a default context that targets the thread pool is used. Handler können mit diesem Ereignis registriert werden.Handlers may be registered with this event. Ein einzelner Handler kann auch dem Progress<T>-Konstruktor nach Wunsch bereitgestellt werden und verhält sich wie ein Ereignishandler für das ProgressChanged-Ereignis.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. Statusupdates werden asynchron ausgelöst, um den asynchronen Vorgang zu verzögern, während der Ereignishandler ausgeführt wird.Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. Eine andere IProgress<T>-Implementierung kann festlegen, dass andere Semantik anzuwenden ist.Another IProgress<T> implementation could choose to apply different semantics.

Auswählen der bereitzustellenden ÜberladungenChoosing the overloads to provide

Verwendet eine TAP-Implementierung sowohl den optionalen Parameter CancellationToken als auch den optionalen Parameter IProgress<T>, kann dies möglicherweise bis zu vier Überladungen erfordern: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  

Viele TAP-Implementierungen bieten jedoch weder Abbruchs- noch Statusfunktionen und erfordern daher eine einzelne Methode:However, many TAP implementations provide neither cancellation or progress capabilities, so they require a single method:

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

Wenn eine TAP-Implementierung entweder Abbruch oder Status, jedoch nicht beides unterstützt, kann sie zwei Überladungen bereitstellen: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  

Wenn eine TAP-Implementierung Abbruch und Status unterstützt, kann sie alle vier Überladungen verfügbar machen.If a TAP implementation supports both cancellation and progress, it may expose all four overloads. Sie kann jedoch möglicherweise nur die Folgenden zwei bereitstellen: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  

Als Ausgleich für die zwei fehlenden Zwischenkombinationen können Entwickler None oder ein standardmäßiges CancellationToken für den cancellationToken-Parameter und null für den progress-Parameter übergeben.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.

Wenn Sie erwarten, dass jede Verwendung der TAP-Methode Abbruch oder Status unterstützt, können Sie die Überladungen, die den relevanten Parameter nicht akzeptieren, weglassen.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.

Wenn Sie sich dazu entschließen, mehrere Überladungen verfügbar zu machen, um Abbruch und/oder Status optional zu machen, sollte das Verhalten der Überladungen, die Abbruch und/oder Status nicht unterstützen, dem Verhalten einer Überladung entsprechen, die None für Abbruch oder null für Status an die Überladung übergibt, die Abbruch bzw. Status unterstützt.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.

TitelTitle BeschreibungDescription
Muster für die asynchrone ProgrammierungAsynchronous Programming Patterns Stellt die drei Muster zum Ausführen von asynchronen Vorgängen vor: das aufgabenbasierte asynchrone Muster (TAP), das asynchrone Programmiermodell (APM) und das ereignisbasierte asynchrone Muster (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).
Implementieren des aufgabenbasierten asynchronen EntwurfsmustersImplementing the Task-based Asynchronous Pattern Beschreibt, wie Sie das aufgabenbasierte asynchrone Muster (Task-based Asynchronous Pattern, TAP) auf drei Arten implementieren können: mit C# und den Visual Basic-Compilern in Visual Studio, manuell oder mit einer Kombination von Compilermethoden und manuellen Methoden.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.
Nutzen des aufgabenbasierten asynchronen MustersConsuming the Task-based Asynchronous Pattern Beschreibt, wie Sie Aufgaben und Rückrufe verwenden können, um eine Verzögerung ohne Blockierung zu erreichen.Describes how you can use tasks and callbacks to achieve waiting without blocking.
Interoperabilität mit anderen asynchronen Mustern und TypenInterop with Other Asynchronous Patterns and Types Beschreibt, wie das aufgabenbasierte asynchrone Muster (TAP) verwendet werden kann, um das asynchrone Programmiermodell (APM) und das ereignisbasierte asynchrone Muster (EAP) zu implementieren.Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).