Wzorzec asynchroniczny oparty na zadaniach (TAP)Task-based asynchronous pattern (TAP)

Wzorzec asynchroniczny oparty na zadaniach (TAP) jest oparty na System.Threading.Tasks.Task i System.Threading.Tasks.Task<TResult> typach w przestrzeni nazw System.Threading.Tasks, które są używane do reprezentowania dowolnych operacji asynchronicznych.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. Wzorzec TAP jest zalecanym asynchronicznym wzorcem projektowym dla nowych prac deweloperskich.TAP is the recommended asynchronous design pattern for new development.

Nazewnictwo, parametry i typy zwracaneNaming, parameters, and return types

We wzorcu TAP do tworzenia wystąpienia i wykonywania operacji asynchronicznej jest używana jedna metoda.TAP uses a single method to represent the initiation and completion of an asynchronous operation. To różni się od wzorca programowania asynchronicznego (APM lub IAsyncResult) i wzorca asynchronicznego opartego na zdarzeniach (EAP).This contrasts with both the Asynchronous Programming Model (APM or IAsyncResult) pattern and the Event-based Asynchronous Pattern (EAP). System APM wymaga metod Begin i End.APM requires Begin and End methods. Protokół EAP wymaga metody, która ma sufiks Async, a także wymaga co najmniej jednego zdarzenia, typów delegatów obsługi zdarzeń i typów pochodnych 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. Metody asynchroniczne w programie TAP obejmują sufiks Async po nazwie operacji dla metod, które zwracają typy oczekujące, takie jak Task, Task<TResult>, ValueTaski 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>. Na przykład asynchroniczna operacja Get, która zwraca Task<String> można nazwać GetAsync.For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync. Jeśli dodajesz metodę TAP do klasy, która zawiera już nazwę metody EAP z sufiksem Async, zamiast tego użyj sufiksu 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. Na przykład jeśli klasa ma już metodę GetAsync, użyj nazwy GetTaskAsync.For example, if the class already has a GetAsync method, use the name GetTaskAsync. Jeśli metoda rozpoczyna operację asynchroniczną, ale nie zwraca typu oczekującego, jej nazwa powinna rozpoczynać się od Begin, Startlub innego zlecenia, aby zasugerować, że ta metoda nie zwraca lub nie generuje wyniku operacji.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.  

Metoda TAP zwraca System.Threading.Tasks.Task lub System.Threading.Tasks.Task<TResult>, w zależności od tego, czy odpowiadająca metoda synchroniczna zwraca typ void lub 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.

Parametry metody TAP powinny odpowiadać parametrom synchronicznego odpowiednika i powinny być podane w tej samej kolejności.The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. Jednak parametry out i ref są wykluczone z tej reguły i należy je całkowicie uniknąć.However, out and ref parameters are exempt from this rule and should be avoided entirely. Wszelkie dane, które zostałyby zwrócone przez out lub parametr ref, powinny być zwracane jako część TResult zwrócone przez Task<TResult>i powinny używać spójnej struktury danych w celu podzielenia wielu wartości.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. Należy również rozważyć dodanie CancellationToken parametru, nawet jeśli synchroniczny odpowiednik metody TAP nie oferuje tego elementu.You should also consider adding a CancellationToken parameter even if the TAP method's synchronous counterpart does not offer one.

Metody, które są przeznaczone wyłącznie do tworzenia, manipulowania lub łączenia zadań (w przypadku których zamiar asynchroniczny metody jest jasne w nazwie metody lub w nazwie typu, do którego należy Metoda) nie muszą być zgodne z tym wzorcem nazewnictwa; takie metody są często określane jako kombinatorów.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. Przykłady kombinatorów zawierają WhenAll i WhenAnyi zostały omówione w sekcji using wbudowanej kombinatorów opartej na zadaniach w artykule korzystającej ze wzorca asynchronicznego opartego na zadaniach.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.

Aby zapoznać się z przykładami sposobu, w jaki składnia TAP różni się od składni używanej w starszych asynchronicznych wzorcach programowania, takich jak asynchroniczny model programowania (APM) i asynchroniczny wzorzec oparty na zdarzeniach (EAP), zobacz wzorce programowania asynchronicznego.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.

Inicjowanie operacji asynchronicznejInitiating an asynchronous operation

Metoda asynchroniczna oparta na wzorcu TAP może wykonać synchronicznie niewielką ilość pracy, na przykład weryfikację argumentów i inicjowanie operacji asynchronicznej, zanim zwróci zadanie wynikowe.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. Praca synchroniczna powinna być ograniczona do minimum, tak aby metoda asynchroniczna mogła szybko zwracać wynik.Synchronous work should be kept to the minimum so the asynchronous method can return quickly. Powody oczekiwania szybkiego zwrócenia wyniku to m.in.:Reasons for a quick return include the following:

  • Metody asynchroniczne mogą być wywoływane z wątków interfejsu użytkownika (UI), a jakakolwiek długotrwała praca synchroniczna może niekorzystnie wpływać na czas reakcji aplikacji.Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • Wiele metod asynchronicznych może zostać uruchomionych jednocześnie.Multiple asynchronous methods may be launched concurrently. W związku z tym jakakolwiek długotrwała praca synchroniczna metody asynchronicznej może opóźnić zainicjowanie innych operacji asynchronicznych, zmniejszając w ten sposób korzyści płynące ze współbieżności.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.

W niektórych przypadkach nakład pracy wymagany do ukończenia operacji jest mniejszy niż ilość pracy potrzebna do asynchronicznego uruchomienia operacji.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. Przykładem takiego scenariusza jest odczyt ze strumienia, gdzie operacja odczytu może się odbyć dzięki danym buforowanym już w pamięci.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. W takich przypadkach operacja może zakończyć się synchronicznie i może zwracać zadanie, które zostało już zakończone.In such cases, the operation may complete synchronously, and may return a task that has already been completed.

WyjątkiExceptions

Metoda asynchroniczna powinna zgłosić wyjątek z wywołania metody asynchronicznej tylko w odpowiedzi na błąd użycia.An asynchronous method should raise an exception to be thrown out of the asynchronous method call only in response to a usage error. Błędy użycia nie powinny nigdy występować w kodzie produkcyjnym.Usage errors should never occur in production code. Na przykład jeśli przekazywanie odwołania o wartości null (Nothing w Visual Basic) jako jeden z argumentów metody powoduje błąd (zazwyczaj reprezentowany przez wyjątek ArgumentNullException), można zmodyfikować kod wywołujący, aby upewnić się, że odwołanie o wartości null nigdy nie zostanie przekazane.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. W przypadku innych błędów wyjątki, które występują, gdy uruchomiona jest metoda asynchroniczna, powinny być przypisane do zwracanego zadania, nawet jeśli metoda asynchroniczna jest wykonywana synchronicznie przed zwróceniem zadania.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. Zadanie zawiera zazwyczaj co najwyżej jeden wyjątek.Typically, a task contains at most one exception. Jeśli jednak zadanie reprezentuje wiele operacji (na przykład WhenAll), wiele wyjątków może być skojarzonych z pojedynczym zadaniem.However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

Środowisko doceloweTarget environment

Podczas implementacji metody wzorca TAP można określić, gdzie występuje wykonanie asynchroniczne.When you implement a TAP method, you can determine where asynchronous execution occurs. Można wybrać opcję wykonania operacji w puli wątków, zaimplementować je za pomocą asynchronicznego wejścia/wyjścia (bez powiązania z wątkiem dla większości wykonywanych operacji), uruchomić je w określonym wątku (na przykład wątku interfejsu użytkownika) lub użyć dowolnej liczby potencjalnych kontekstów.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. Metoda TAP może nawet nie mieć niczego do wykonania i może po prostu zwrócić Task, która reprezentuje wystąpienie warunku w innym miejscu w systemie (na przykład zadanie, które reprezentuje dane docierające do struktury danych znajdujących się w kolejce).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).

Obiekt wywołujący metody TAP może blokować oczekiwanie na ukończenie metody TAP przez synchronicznie czeka na wyniki zadania lub może uruchamiać dodatkowy kod (kontynuacja) po zakończeniu operacji asynchronicznej.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. Twórca kodu kontynuacji ma kontrolę nad tym, gdzie ten kod jest wykonywany.The creator of the continuation code has control over where that code executes. Kod kontynuacji można utworzyć jawnie, za pomocą metod klasy Task (na przykład ContinueWith) lub niejawnie, przy użyciu obsługi języka, która jest oparta na kontynuacji (na przykład await w C#Await w Visual Basic, AwaitValue w F#systemie).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#).

Stan zadaniaTask status

Klasa Task dostarcza cykl życia operacji asynchronicznych i ten cykl jest reprezentowany przez Wyliczenie TaskStatus.The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. Aby obsługiwać przypadki narożne typów, które pochodzą z Task i Task<TResult>i aby obsługiwać separację konstrukcji z planowania, Klasa Task uwidacznia metodę 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. Zadania, które są tworzone przez publiczne konstruktory Task, są określane jako zimne zadania, ponieważ zaczynają ich cykl życia w stanie zaplanowanym Created i są planowane tylko wtedy, gdy Start jest wywoływana dla tych wystąpień.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.

Wszystkie inne zadania rozpoczynają cykl życia w stanie gorąca, co oznacza, że operacje asynchroniczne, które reprezentują, zostały już zainicjowane, a ich stan zadania jest wartością wyliczenia inną niż 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. Wszystkie zadania, które są zwracane z metod wzorca TAP, muszą być aktywowane.All tasks that are returned from TAP methods must be activated. Jeśli metoda TAP używa wewnętrznie konstruktora zadania, aby utworzyć wystąpienie zadania do zwrócenia, Metoda TAP musi wywołać Start na obiekcie Task przed jego zwróceniem.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. Konsumenci metody TAP mogą bezpiecznie założyć, że zwrócone zadanie jest aktywne i nie powinna próbować wywołać Start na żadnym Task, który jest zwracany przez metodę 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. Wywołanie Start na aktywnym zadaniu powoduje wystąpienie InvalidOperationException wyjątku.Calling Start on an active task results in an InvalidOperationException exception.

Anulowanie (opcjonalne)Cancellation (optional)

We wzorcu TAP anulowanie jest opcjonalne dla implementatorów metody asynchronicznej i konsumentów metody asynchronicznej.In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. Jeśli operacja zezwala na anulowanie, ujawnia Przeciążenie metody asynchronicznej, która akceptuje token anulowania (CancellationToken wystąpienie).If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). Zgodnie z Konwencją parametr ma nazwę 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

Operacja asynchroniczna monitoruje ten token pod kątem żądań anulowania.The asynchronous operation monitors this token for cancellation requests. Jeśli odbierze żądanie anulowania, może je zaakceptować i anulować operację.If it receives a cancellation request, it may choose to honor that request and cancel the operation. Jeśli żądanie anulowania spowoduje przedwcześnie zakończenie pracy, Metoda TAP zwraca zadanie, które kończy się w stanie Canceled; Brak dostępnego wyniku i nie został zgłoszony żaden wyjątek.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. Stan Canceled jest uznawany za końcowy (ukończony) dla zadania, wraz ze Stanami Faulted i RanToCompletion.The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. W związku z tym, jeśli zadanie jest w stanie Canceled, jego właściwość IsCompleted zwraca true.Therefore, if a task is in the Canceled state, its IsCompleted property returns true. Gdy zadanie zostanie ukończone w stanie Canceled, wszystkie kontynuacje zarejestrowane w ramach zadania są zaplanowane lub wykonywane, chyba że opcja kontynuacji, taka jak NotOnCanceled, została określona w celu rezygnacji z kontynuacji.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. Każdy kod, który asynchronicznie czeka na anulowane zadanie przy użyciu funkcji języka, jest nadal uruchamiany, ale odbiera OperationCanceledException lub wyjątek pochodzący od niego.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. Kod, który jest blokowany synchronicznie, oczekując na zadanie za pomocą metod takich jak Wait i WaitAll również nadal uruchamiany z wyjątkiem.Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

Jeśli token anulowania zażądał anulowania przed wywołaniem metody, która akceptuje ten token, Metoda TAP powinna zwracać Canceled zadanie.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. Jeśli jednak żądanie anulowania zostanie zgłoszone, gdy trwa operacja asynchroniczna, operacja asynchroniczna nie musi akceptować żądania anulowania.However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. Zwrócone zadanie powinno kończyć się w stanie Canceled tylko wtedy, gdy operacja kończy się w wyniku żądania anulowania.The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. Jeśli zażądano anulowania, ale nadal jest generowany wynik lub wyjątek, zadanie powinno kończyć się w stanie RanToCompletion lub Faulted.If cancellation is requested but a result or an exception is still produced, the task should end in the RanToCompletion or Faulted state.

W przypadku metod asynchronicznych, które chcą ujawnić możliwość pierwszego i przedniego anulowania, nie trzeba podawać przeciążenia, które nie akceptuje tokenu anulowania.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. W przypadku metod, które nie mogą być anulowane, nie należy dostarczać przeciążeń, które akceptują token anulowania. Pomaga to wskazać obiektowi wywołującemu, czy metodę docelową można w rzeczywistości anulować.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. Kod klienta, który nie wymaga anulowania, może wywołać metodę, która akceptuje CancellationToken i podać None jako wartość argumentu.Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None jest funkcjonalnie równoważny CancellationTokendomyślnej.None is functionally equivalent to the default CancellationToken.

Raportowanie postępu (opcjonalnie)Progress reporting (optional)

Niektóre operacje asynchroniczne korzystają z dostarczania powiadomień na temat postępu. Zazwyczaj są one używane do aktualizowania interfejsu użytkownika za pomocą informacji o postępie operacji asynchronicznej.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.

W programie TAP postęp jest obsługiwany przez interfejs IProgress<T>, który jest przesyłany do metody asynchronicznej jako parametr, który jest zazwyczaj nazwany 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. Dostarczenie interfejsu postępu, gdy wywoływana jest metoda asynchroniczna, pomaga wyeliminować sytuację wyścigu, która wynika z niepoprawnego użycia (tzn. kiedy obsługa zdarzeń, która jest niepoprawnie rejestrowana po rozpoczęciu operacji, może pominąć aktualizacje).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). Co więcej, interfejs postępu obsługuje różne implementacje postępu, co zostało określone przez kod konsumencki.More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. Kod konsumencki może uwzględniać tylko najnowszą aktualizację postępu lub może buforować wszystkie aktualizacje. Może on wywołać akcję dla każdej aktualizacji lub może określać, czy wywołanie jest przekazywane do określonego wątku.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. Te opcje można osiągnąć przy użyciu różnej implementacji interfejsu, dostosowanej do potrzeb danego konsumenta.All these options may be achieved by using a different implementation of the interface, customized to the particular consumer’s needs. Podobnie jak w przypadku anulowania, implementacje programu TAP powinny podawać parametr IProgress<T> tylko wtedy, gdy interfejs API obsługuje powiadomienia o postępie.As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

Na przykład jeśli metoda ReadAsync opisana wcześniej w tym artykule jest w stanie raportować postęp pośredni w postaci liczby odczytanych bajtów w tym zakresie, wywołanie zwrotne postępu może być interfejsem 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 

Jeśli metoda FindFilesAsync zwraca listę wszystkich plików, które spełniają określony wzorzec wyszukiwania, wywołanie zwrotne postępu może zapewnić oszacowanie wartości procentowej wykonanej pracy, a także bieżący zestaw wyników częściowych.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. Może to zrobić za pomocą spójnej kolekcji: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))

lub za pomocą typu danych specyficznego dla interfejsu 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))

W tym drugim przypadku specjalny typ danych jest zazwyczaj sufiksem ProgressInfo.In the latter case, the special data type is usually suffixed with ProgressInfo.

Jeśli implementacje TAP zapewniają przeciążenia, które akceptują parametr progress, muszą zezwalać na nullargumentu, w takim przypadku nie zostanie zgłoszony żaden postęp.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. Implementacje TAP powinny raportować postęp do obiektu Progress<T> synchronicznie, dzięki czemu Metoda asynchroniczna może szybko zapewnić postęp, a następnie zezwolić konsumentowi postępu na ustalenie, jak i gdzie najlepiej obsługiwać te informacje.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. Na przykład wystąpienie postępu może wybrać przekazywanie wywołań zwrotnych i generowanie zdarzeń w kontekście przechwyconych synchronizacji.For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

Implementacje > IProgress<TIProgress<T> implementations

.NET Framework 4,5 zawiera jedną implementację IProgress<T>: Progress<T>.The .NET Framework 4.5 provides a single IProgress<T> implementation: Progress<T>. Klasa Progress<T> jest zadeklarowana w następujący sposób: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  

Wystąpienie Progress<T> uwidacznia zdarzenie ProgressChanged, które jest wywoływane za każdym razem, gdy operacja asynchroniczna zgłosi aktualizację postępu.An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. Zdarzenie ProgressChanged jest zgłaszane na obiekcie SynchronizationContext, który został przechwycony podczas tworzenia wystąpienia Progress<T> wystąpieniem.The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. Jeśli kontekst synchronizacji nie był dostępny, używany jest domyślny kontekst ukierunkowany na pulę wątków.If no synchronization context was available, a default context that targets the thread pool is used. Z tym zdarzeniem można zarejestrować programy obsługi.Handlers may be registered with this event. Pojedynczy program obsługi może być również udostępniony konstruktorowi Progress<T> dla wygody i zachowuje się tak jak program obsługi zdarzeń dla zdarzenia 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. Aktualizacje postępu są wywoływane asynchronicznie, aby unikać opóźniania operacji asynchronicznej podczas wykonywania obsługi zdarzeń.Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. Inna implementacja IProgress<T> może zdecydować się na zastosowanie różnych semantyki.Another IProgress<T> implementation could choose to apply different semantics.

Wybieranie przeciążeń do dostarczeniaChoosing the overloads to provide

Jeśli implementacja TAP używa zarówno opcjonalne CancellationToken, jak i opcjonalnych parametrów IProgress<T>, może to wymagać do czterech przeciążeń: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  

Wiele implementacji wzorca TAP nie dostarcza jednak możliwości anulowania ani możliwości obsługi postępu, więc wymagają one pojedynczej metody:However, many TAP implementations provide neither cancellation or progress capabilities, so they require a single method:

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

Jeżeli implementacja wzorca TAP obsługuje anulowanie lub postęp, ale nie obie te możliwości naraz, może ona dostarczać dwa przeciążenia: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  

Jeśli implementacja wzorca TAP obsługuje zarówno anulowanie, jak i postęp, może uwidaczniać wszystkie cztery przeciążenia.If a TAP implementation supports both cancellation and progress, it may expose all four overloads. Może jednak dostarczyć tylko następujące dwa: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  

Aby skompensować dla dwóch brakujących się kombinacji pośrednich, deweloperzy mogą przekazywać None lub CancellationToken domyślny dla parametru cancellationToken i null dla parametru 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.

Jeśli każde użycie metody wzorca TAP ma obsługiwać anulowanie lub postęp, możesz pominąć przeciążenia, które nie akceptują odpowiedniego parametru.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.

W przypadku podjęcia decyzji o udostępnieniu wielu przeciążeń w celu dokonania anulowania lub załadowania, przeciążenia, które nie obsługują anulowania lub postępu, powinny zachowywać się tak, jakby przechodzą None do anulowania lub null do przeładowania do przeciążenia, które je obsługują.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.

TytułTitle OpisDescription
Wzorce programowania asynchronicznegoAsynchronous Programming Patterns Wprowadza trzy wzorce do wykonywania operacji asynchronicznych: asynchroniczny wzorzec oparty na zadaniach (TAP), asynchroniczny model programowania (APM) i asynchroniczny wzorzec oparty na zdarzeniach (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).
Implementowanie wzorca asynchronicznego opartego na zadaniachImplementing the Task-based Asynchronous Pattern Opis sposobu implementacji asynchronicznego wzorca opartego na zadaniach (TAP), którą można przeprowadzić na trzy sposoby: za pomocą kompilatorów języków C# i Visual Basic w programie Visual Studio, ręcznie lub za pomocą kombinacji metod kompilatora i manualnych.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.
Wykorzystywanie wzorca asynchronicznego opartego na zadaniachConsuming the Task-based Asynchronous Pattern Opis sposobu używania zadań i wywołań zwrotnych w celu osiągnięcia oczekiwania bez blokowania.Describes how you can use tasks and callbacks to achieve waiting without blocking.
Współdziałanie z innymi wzorcami asynchronicznymi i typamiInterop with Other Asynchronous Patterns and Types Opis sposobu używania asynchronicznego wzorca opartego na zadaniach (TAP) w celu implementacji asynchronicznego modelu programowania (APM) i asynchronicznego wzorca opartego na zdarzeniach (EAP).Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).