Model programowania asynchronicznego zadań (APM)Task asynchronous programming model

Możesz uniknąć problemów z wydajnością i poprawić ogólny czas odpowiedzi aplikacji, stosując programowanie asynchroniczne.You can avoid performance bottlenecks and enhance the overall responsiveness of your application by using asynchronous programming. Jednak tradycyjne techniki pisania aplikacji asynchronicznych mogą być skomplikowane, przez co trudne do pisania, debugowania i konserwacji.However, traditional techniques for writing asynchronous applications can be complicated, making them difficult to write, debug, and maintain.

5 wprowadzono uproszczone podejście, programowanie asynchroniczne, które wykorzystuje asynchroniczne wsparcie w .NET Framework 4,5 i wyższych, .NET Core i środowisko wykonawcze systemu Windows. C# C# 5 introduced a simplified approach, async programming, that leverages asynchronous support in the .NET Framework 4.5 and higher, .NET Core, and the Windows Runtime. Kompilator wykonuje trudną pracę, którą kiedyś wykonywał programista, a aplikacja zachowuje strukturę logiczną przypominającą kod synchroniczny.The compiler does the difficult work that the developer used to do, and your application retains a logical structure that resembles synchronous code. W efekcie masz wszystkie korzyści wynikające z programowania asynchronicznego przy ułamkowym nakładzie pracy.As a result, you get all the advantages of asynchronous programming with a fraction of the effort.

Ten temat zawiera omówienie, kiedy i jak stosować programowanie async oraz zawiera łącza do tematów zawierających szczegółowe informacje oraz przykłady.This topic provides an overview of when and how to use async programming and includes links to support topics that contain details and examples.

Asynchroniczne zwiększenie czasu odpowiedziAsync improves responsiveness

Asynchroniczności jest istotna dla działań, które mogą być blokowane, takich jak dostęp do sieci Web.Asynchrony is essential for activities that are potentially blocking, such as web access. Dostęp do zasobów sieci Web bywa powolny lub opóźniony.Access to a web resource sometimes is slow or delayed. Jeśli takie działanie jest zablokowane w procesie synchronicznym, cała aplikacja musi czekać.If such an activity is blocked in a synchronous process, the entire application must wait. W procesie asynchronicznym aplikacja może kontynuować wykonywanie innych zadań, które nie są zależne od zasobów sieci Web, do momentu zakończeniem zadania mogącego powodować blokowanie.In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.

W poniższej tabeli przedstawiono typowe obszary, w których programowanie asynchroniczne poprawia czas odpowiedzi.The following table shows typical areas where asynchronous programming improves responsiveness. Wymienione interfejsy API platformy .NET i środowisko wykonawcze systemu Windows zawierają metody, które obsługują programowanie asynchroniczne.The listed APIs from .NET and the Windows Runtime contain methods that support async programming.

Obszar aplikacjiApplication area Typy .NET z metodami asynchronicznymi.NET types with async methods Typy środowisko wykonawcze systemu Windows z metodami asynchronicznymiWindows Runtime types with async methods
Web accessWeb access HttpClient SyndicationClient
Praca z plikamiWorking with files StreamWriter, StreamReader, XmlReaderStreamWriter, StreamReader, XmlReader StorageFile
Praca z obrazamiWorking with images MediaCapture, BitmapEncoder, BitmapDecoderMediaCapture, BitmapEncoder, BitmapDecoder
Programowanie WCFWCF programming Operacje synchroniczne i asynchroniczneSynchronous and Asynchronous Operations

Asynchroniczność okazuje się szczególnie cenna w przypadku aplikacji, które mają dostęp do wątku interfejsu użytkownika, ponieważ wszystkie działania związane z interfejsem użytkownika korzystają zazwyczaj z jednego wątku.Asynchrony proves especially valuable for applications that access the UI thread because all UI-related activity usually shares one thread. Jeśli w aplikacji synchronicznej jest zablokowany jakikolwiek proces, zablokowane są wszystkie procesy.If any process is blocked in a synchronous application, all are blocked. Aplikacja przestanie odpowiadać i możesz dojść do wniosku, że uległa awarii, a tymczasem może po prostu być w stanie oczekiwania.Your application stops responding, and you might conclude that it has failed when instead it's just waiting.

Kiedy używasz metod asynchronicznych, aplikacja dalej odpowiada interfejsowi użytkownika.When you use asynchronous methods, the application continues to respond to the UI. Możesz przykładowo zmienić rozmiar lub zminimalizować aplikację lub możesz ją zamknąć, jeżeli nie chcesz czekać aż zakończy zadanie.You can resize or minimize a window, for example, or you can close the application if you don't want to wait for it to finish.

Podejście async oferuje również odpowiednik automatycznego przejścia do listy opcji do wybrania przy projektowaniu operacji asynchronicznych.The async-based approach adds the equivalent of an automatic transmission to the list of options that you can choose from when designing asynchronous operations. Oznacza to, że można korzystać z wszystkich zalet tradycyjnego programowania asynchronicznego, ale przy znacznie mniejszym nakładzie pracy programisty.That is, you get all the benefits of traditional asynchronous programming but with much less effort from the developer.

Metody asynchroniczne są łatwiejsze do zapisuAsync methods are easier to write

Słowa kluczowe Async i await w C# programie to serce programowanie asynchroniczne.The async and await keywords in C# are the heart of async programming. Korzystając z tych dwóch słów kluczowych, można użyć zasobów w .NET Framework, .NET Core lub środowisko wykonawcze systemu Windows, aby szybko utworzyć metodę asynchroniczną niemal jak w przypadku tworzenia metody synchronicznej.By using those two keywords, you can use resources in the .NET Framework, .NET Core, or the Windows Runtime to create an asynchronous method almost as easily as you create a synchronous method. Metody asynchroniczne zdefiniowane za pomocą słowa kluczowego async są określane jako metody async.Asynchronous methods that you define by using the async keyword are referred to as async methods.

W poniższym przykładzie przedstawiono metodę async.The following example shows an async method. Prawie wszystko w kodzie powinno wyglądać znajomo.Almost everything in the code should look completely familiar to you.

Kompletny przykładowy plik Windows Presentation Foundation (WPF) można znaleźć na końcu tego tematu i można pobrać przykład z przykład Async: przykład z "programowania asynchronicznego z Async i await".You can find a complete Windows Presentation Foundation (WPF) example file at the end of this topic, and you can download the sample from Async Sample: Example from "Asynchronous Programming with Async and Await".

async Task<int> AccessTheWebAsync()
{
    // You need to add a reference to System.Net.Http to declare client.
    var client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("https://docs.microsoft.com/dotnet");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync.
    //  - AccessTheWebAsync can't continue until getStringTask is complete.
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync.
    //  - Control resumes here when getStringTask is complete.
    //  - The await operator then retrieves the string result from getStringTask.
    string urlContents = await getStringTask;

    // The return statement specifies an integer result.
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value.
    return urlContents.Length;
}

Możesz poznać kilka praktyk z powyższego przykładu.You can learn several practices from the preceding sample. Zacznij od sygnatury metody.Start with the method signature. Zawiera modyfikator async.It includes the async modifier. Zwracany typ jest Task<int> (zobacz sekcję "typy zwracane", aby uzyskać więcej opcji).The return type is Task<int> (See "Return Types" section for more options). Nazwa metody zostaje zakończona w Async.The method name ends in Async. W treści metody GetStringAsync zwraca Task<string>.In the body of the method, GetStringAsync returns a Task<string>. Oznacza to, że podczas await zadania uzyskasz string (urlContents).That means that when you await the task you'll get a string (urlContents). Przed oczekiwaniem na zadanie można wykonać zadania, które nie bazują na string z GetStringAsync.Before awaiting the task, you can do work that doesn't rely on the string from GetStringAsync.

Zwróć szczególną uwagę na operator await.Pay close attention to the await operator. Wstrzymuje AccessTheWebAsync;It suspends AccessTheWebAsync;

  • nie można kontynuować AccessTheWebAsync do momentu zakończenia getStringTask.AccessTheWebAsync can't continue until getStringTask is complete.
  • W tym czasie sterowanie powraca do obiektu wywołującego AccessTheWebAsync.Meanwhile, control returns to the caller of AccessTheWebAsync.
  • Formant zostanie wznowiony w tym miejscu po zakończeniu getStringTask.Control resumes here when getStringTask is complete.
  • Następnie operator await pobiera wynik string z getStringTask.The await operator then retrieves the string result from getStringTask.

Instrukcja return określa wynik w postaci liczby całkowitej.The return statement specifies an integer result. Wszystkie metody, które oczekują na AccessTheWebAsync pobranie wartości długości.Any methods that are awaiting AccessTheWebAsync retrieve the length value.

Jeśli AccessTheWebAsync nie ma żadnej pracy, którą może wykonać między wywołaniem GetStringAsync i oczekiwaniem na jego zakończenie, można uprościć kod, wywołując i await w następującej pojedynczej instrukcji.If AccessTheWebAsync doesn't have any work that it can do between calling GetStringAsync and awaiting its completion, you can simplify your code by calling and awaiting in the following single statement.

string urlContents = await client.GetStringAsync("https://docs.microsoft.com/dotnet");

Poniższe cechy podsumowują, co sprawia, że w poprzednim przykładzie metoda async:The following characteristics summarize what makes the previous example an async method:

  • Podpis metody zawiera modyfikator async.The method signature includes an async modifier.

  • Nazwa metody async kończy się zwyczajowo sufiksem „Async”.The name of an async method, by convention, ends with an "Async" suffix.

  • Zwracany typ może być jednym z następujących:The return type is one of the following types:

    • Task<TResult>, jeśli metoda zawiera instrukcję return, w której operand ma typ TResult.Task<TResult> if your method has a return statement in which the operand has type TResult.
    • Task, jeśli metoda nie zawiera instrukcji return lub zawiera instrukcję return bez operandu.Task if your method has no return statement or has a return statement with no operand.
    • void, jeśli piszesz procedurę obsługi zdarzeń asynchronicznych.void if you're writing an async event handler.
    • Każdy inny typ, który ma metodę GetAwaiter (Zaczynając od C# 7,0).Any other type that has a GetAwaiter method (starting with C# 7.0).

    Aby uzyskać więcej informacji, zobacz sekcję typy zwracane i parametry .For more information, see the Return Types and Parameters section.

  • Metoda zwykle zawiera co najmniej jedno wyrażenie await, które oznacza punkt, w którym metoda nie może kontynuować pracy, dopóki nie zostanie ukończona oczekująca operacja asynchroniczna.The method usually includes at least one await expression, which marks a point where the method can't continue until the awaited asynchronous operation is complete. W tym czasie metoda jest zawieszona, a sterowanie powraca do obiektu wywołującego metodę.In the meantime, the method is suspended, and control returns to the method's caller. Następna sekcji tego tematu przedstawia, co się dzieje w punkcie zawieszenia.The next section of this topic illustrates what happens at the suspension point.

W metodzie asynchronicznej używasz podanych słów kluczowych i typów w celu wskazania, co chcesz zrobić, a kompilator zajmie się resztą, w tym śledzeniem tego, co musi się zdarzyć, gdy sterowanie powraca do punktu oczekiwania w metodzie zawieszonej.In async methods, you use the provided keywords and types to indicate what you want to do, and the compiler does the rest, including keeping track of what must happen when control returns to an await point in a suspended method. Niektóre procesy, takie jak pętle i obsługa wyjątków, mogą być trudne do obsłużenia w tradycyjnym kodzie asynchronicznym.Some routine processes, such as loops and exception handling, can be difficult to handle in traditional asynchronous code. W metodzie asynchronicznej wpisujesz te elementy podobnie jak w rozwiązaniu synchronicznym i problem rozwiązany.In an async method, you write these elements much as you would in a synchronous solution, and the problem is solved.

Aby uzyskać więcej informacji na temat asynchroniczności w poprzednich wersjach .NET Framework, zobacz TPL i tradycyjne .NET Framework programowanie asynchroniczne.For more information about asynchrony in previous versions of the .NET Framework, see TPL and Traditional .NET Framework Asynchronous Programming.

Co dzieje się w metodzie asynchronicznejWhat happens in an async method

Ważne jest, aby rozumieć programowanie asynchroniczne jako przepływ sterowania od metody do metody.The most important thing to understand in asynchronous programming is how the control flow moves from method to method. Poniższy diagram przeprowadzi Cię przez proces:The following diagram leads you through the process:

Śledzenie programu asynchronicznegoTrace an async program

Liczby na diagramie odpowiadają następującym krokom, inicjowanym po kliknięciu przycisku "Start" przez użytkownika.The numbers in the diagram correspond to the following steps, initiated when the user clicks the "start" button.

  1. Program obsługi zdarzeń wywołuje i czeka na metodę asynchroniczną AccessTheWebAsync.An event handler calls and awaits the AccessTheWebAsync async method.

  2. AccessTheWebAsync tworzy wystąpienie HttpClient i wywołuje GetStringAsync metodę asynchroniczną, aby pobrać zawartość witryny sieci Web jako ciąg.AccessTheWebAsync creates an HttpClient instance and calls the GetStringAsync asynchronous method to download the contents of a website as a string.

  3. Coś się dzieje w GetStringAsync, które zawiesza postępy.Something happens in GetStringAsync that suspends its progress. Być może metoda musi czekać na pobranie strony internetowej lub inne działanie blokujące.Perhaps it must wait for a website to download or some other blocking activity. Aby uniknąć blokowania zasobów, GetStringAsync przekazuje kontrolę do obiektu wywołującego, AccessTheWebAsync.To avoid blocking resources, GetStringAsync yields control to its caller, AccessTheWebAsync.

    GetStringAsync zwraca Task<TResult>, gdzie TResult jest ciągiem, a AccessTheWebAsync przypisuje zadanie do zmiennej getStringTask.GetStringAsync returns a Task<TResult>, where TResult is a string, and AccessTheWebAsync assigns the task to the getStringTask variable. Zadanie reprezentuje proces trwającego wywołania GetStringAsync, z zobowiązaniem do utworzenia rzeczywistej wartości ciągu po zakończeniu pracy.The task represents the ongoing process for the call to GetStringAsync, with a commitment to produce an actual string value when the work is complete.

  4. Ponieważ getStringTask nie została jeszcze zainicjowana, AccessTheWebAsync może kontynuować pracę z innymi zadaniami, które nie zależą od końcowego wyniku GetStringAsync.Because getStringTask hasn't been awaited yet, AccessTheWebAsync can continue with other work that doesn't depend on the final result from GetStringAsync. To działanie jest reprezentowane przez wywołanie metody synchronicznej DoIndependentWork.That work is represented by a call to the synchronous method DoIndependentWork.

  5. DoIndependentWork to metoda synchroniczna, która wykonuje jej działanie i powraca do obiektu wywołującego.DoIndependentWork is a synchronous method that does its work and returns to its caller.

  6. AccessTheWebAsync zabrakło pracy, którą może wykonać bez wyniku z getStringTask.AccessTheWebAsync has run out of work that it can do without a result from getStringTask. AccessTheWebAsync dalej chce obliczyć i zwrócić długość pobranego ciągu, ale metoda nie może obliczyć tej wartości, dopóki metoda nie ma ciągu.AccessTheWebAsync next wants to calculate and return the length of the downloaded string, but the method can't calculate that value until the method has the string.

    W związku z tym, AccessTheWebAsync używa operatora await, aby zawiesić postęp i przekazać kontrolę do metody, która wywołała AccessTheWebAsync.Therefore, AccessTheWebAsync uses an await operator to suspend its progress and to yield control to the method that called AccessTheWebAsync. AccessTheWebAsync zwraca Task<int> do obiektu wywołującego.AccessTheWebAsync returns a Task<int> to the caller. Zadanie przedstawia obietnicę utworzenia w wyniku liczby całkowitej, która jest długością pobranego ciągu.The task represents a promise to produce an integer result that's the length of the downloaded string.

    Uwaga

    Jeśli GetStringAsync (i w związku z tym getStringTask) kończy przed AccessTheWebAsync oczekuje na to, formant pozostaje w AccessTheWebAsync.If GetStringAsync (and therefore getStringTask) completes before AccessTheWebAsync awaits it, control remains in AccessTheWebAsync. Koszt zawieszenia, a następnie powrotu do AccessTheWebAsync byłby tracony, jeśli wywołany proces asynchroniczny (getStringTask) został już ukończony i AccessTheWebAsync nie musi czekać na wynik końcowy.The expense of suspending and then returning to AccessTheWebAsync would be wasted if the called asynchronous process (getStringTask) has already completed and AccessTheWebAsync doesn't have to wait for the final result.

    Przetwarzanie wzorca jest kontynuowane wewnątrz elementu wywołującego (programu obsługi zdarzeń w tym przykładzie).Inside the caller (the event handler in this example), the processing pattern continues. Obiekt wywołujący może wykonywać inne zadania, które nie są zależne od wyniku AccessTheWebAsync przed oczekiwaniem na ten wynik, lub obiekt wywołujący może natychmiast oczekiwać.The caller might do other work that doesn't depend on the result from AccessTheWebAsync before awaiting that result, or the caller might await immediately. Program obsługi zdarzeń oczekuje na AccessTheWebAsync, a AccessTheWebAsync oczekuje na GetStringAsync.The event handler is waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync.

  7. GetStringAsync uzupełnia i generuje wynik w postaci ciągu.GetStringAsync completes and produces a string result. Wynik ciągu nie jest zwracany przez wywołanie do GetStringAsync w oczekiwany sposób.The string result isn't returned by the call to GetStringAsync in the way that you might expect. (Należy pamiętać, że metoda zwróciła już zadanie w kroku 3). Zamiast tego wynik w postaci ciągu jest przechowywany w zadaniu, które reprezentuje zakończenie metody, getStringTask.(Remember that the method already returned a task in step 3.) Instead, the string result is stored in the task that represents the completion of the method, getStringTask. Operator await pobiera wynik z getStringTask.The await operator retrieves the result from getStringTask. Instrukcja przypisania przypisuje pobrany wynik do urlContents.The assignment statement assigns the retrieved result to urlContents.

  8. Gdy AccessTheWebAsync ma wynik ciągu, Metoda może obliczyć długość ciągu.When AccessTheWebAsync has the string result, the method can calculate the length of the string. Następnie zakończenie pracy AccessTheWebAsync jest również możliwe, a procedura obsługi zdarzeń oczekujących może zostać wznowiona.Then the work of AccessTheWebAsync is also complete, and the waiting event handler can resume. W pełnym przykładzie na końcu tematu można zobaczyć, że program obsługi zdarzeń pobiera i drukuje wynikową wartość długości.In the full example at the end of the topic, you can confirm that the event handler retrieves and prints the value of the length result. Jeśli dopiero zaczynasz przygodę z programowaniem asynchronicznym, zastanów się przez chwilę, jaka jest różnica między zachowaniem synchronicznym i asynchronicznym.If you are new to asynchronous programming, take a minute to consider the difference between synchronous and asynchronous behavior. Metoda synchroniczna kończy działanie, gdy praca jest zakończona (krok 5), natomiast metoda asynchroniczna zwraca wartość zadania, gdy jej praca jest zawieszona (kroki 3 i 6).A synchronous method returns when its work is complete (step 5), but an async method returns a task value when its work is suspended (steps 3 and 6). Gdy metoda async ukończy pracę, zadanie jest oznaczane jako ukończone, a wynik, o ile istnieje, jest zapisywany w zadaniu.When the async method eventually completes its work, the task is marked as completed and the result, if any, is stored in the task.

Aby uzyskać więcej informacji o przepływie sterowania, zobacz sterowanie przepływem wC#programach asynchronicznych ().For more information about control flow, see Control Flow in Async Programs (C#).

Metody asynchroniczne interfejsu APIAPI async methods

Być może zastanawiasz się, gdzie można znaleźć metody, takie jak GetStringAsync, które obsługują programowanie asynchroniczne.You might be wondering where to find methods such as GetStringAsync that support async programming. .NET Framework 4,5 lub nowszy i .NET Core zawierają wiele elementów członkowskich, które współpracują z async i await.The .NET Framework 4.5 or higher and .NET Core contain many members that work with async and await. Można je rozpoznać za pomocą sufiksu "Async", który jest dołączany do nazwy elementu członkowskiego i typu zwracanego Task lub Task<TResult>.You can recognize them by the "Async" suffix that's appended to the member name, and by their return type of Task or Task<TResult>. Na przykład Klasa System.IO.Stream zawiera metody, takie jak CopyToAsync, ReadAsynci WriteAsync obok metod synchronicznych CopyTo, Readi Write.For example, the System.IO.Stream class contains methods such as CopyToAsync, ReadAsync, and WriteAsync alongside the synchronous methods CopyTo, Read, and Write.

Środowisko wykonawcze systemu Windows również zawiera wiele metod, których można używać z async i await w aplikacjach systemu Windows.The Windows Runtime also contains many methods that you can use with async and await in Windows apps. Aby uzyskać więcej informacji, zobacz wątkowość i programowanie asynchroniczne dla programowania platformy UWP oraz programowanie asynchroniczne (aplikacje do sklepu Windows) i Szybki Start: wywoływanie C# asynchronicznych interfejsów API w programie lub Visual Basic , jeśli używasz wcześniejszych wersji środowisko wykonawcze systemu Windows.For more information, see Threading and async programming for UWP development, and Asynchronous programming (Windows Store apps) and Quickstart: Calling asynchronous APIs in C# or Visual Basic if you use earlier versions of the Windows Runtime.

WątkThreads

Metody async mają być operacjami niepowodującymi blokowania.Async methods are intended to be non-blocking operations. Wyrażenie await w metodzie asynchronicznej nie blokuje bieżącego wątku, gdy oczekiwane zadanie jest uruchomione.An await expression in an async method doesn't block the current thread while the awaited task is running. Zamiast tego, wyrażenie rejestruje pozostałą część metody jako kontynuację i przekazuje sterowanie do obiektu wywołującego metody async.Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.

Słowa kluczowe async i await nie powodują tworzenia dodatkowych wątków.The async and await keywords don't cause additional threads to be created. Metody komunikacji async nie wymagają wielowątkowości, ponieważ nie działają we własnym wątku.Async methods don't require multithreading because an async method doesn't run on its own thread. Metoda działa w bieżącym kontekście synchronizacji i używa czasu wątku, tylko wtedy, gdy jest aktywna.The method runs on the current synchronization context and uses time on the thread only when the method is active. Za pomocą Task.Run można przenieść zadania powiązane z PROCESORem do wątku w tle, ale wątek w tle nie jest w stanie pomóc w przypadku procesu, który tylko oczekuje na dostępność wyników.You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

Podejście async do programowania asynchronicznego jest preferowane prawie w każdym przypadku.The async-based approach to asynchronous programming is preferable to existing approaches in almost every case. W szczególności ta metoda jest lepsza niż Klasa BackgroundWorker dla operacji we/wy, ponieważ kod jest prostszy i nie trzeba chronić przed warunkami wyścigu.In particular, this approach is better than the BackgroundWorker class for I/O-bound operations because the code is simpler and you don't have to guard against race conditions. W połączeniu z metodą Task.Run, programowanie asynchroniczne jest lepsze niż BackgroundWorker w przypadku operacji związanych z PROCESORem, ponieważ programowanie asynchroniczne oddziela szczegóły koordynacji uruchamiania kodu z pracy, która Task.Run transferuje do puli wątków.In combination with the Task.Run method, async programming is better than BackgroundWorker for CPU-bound operations because async programming separates the coordination details of running your code from the work that Task.Run transfers to the threadpool.

Async i awaitasync and await

Jeśli określisz, że metoda jest metodą asynchroniczną przy użyciu modyfikatora Async , włączysz następujące dwie możliwości.If you specify that a method is an async method by using the async modifier, you enable the following two capabilities.

  • Oznaczona Metoda async może użyć oczekiwania do wyznaczenia punktów zawieszenia.The marked async method can use await to designate suspension points. Operator await informuje kompilator, że metoda async nie może kontynuować tego punktu do momentu zakończenia procesu asynchronicznego oczekiwania.The await operator tells the compiler that the async method can't continue past that point until the awaited asynchronous process is complete. W międzyczasie sterowanie powraca do obiektu wywołującego metodę async.In the meantime, control returns to the caller of the async method.

    Zawieszenie metody asynchronicznej w wyrażeniu await nie stanowi wyjścia z metody, a bloki finally nie są uruchamiane.The suspension of an async method at an await expression doesn't constitute an exit from the method, and finally blocks don't run.

  • Metoda oznaczona jako async sama może być oczekiwana przez metody, które ją wywołują.The marked async method can itself be awaited by methods that call it.

Metoda async zwykle zawiera co najmniej jedno wystąpienie operatora await, ale brak wyrażeń await nie powoduje błędu kompilatora.An async method typically contains one or more occurrences of an await operator, but the absence of await expressions doesn't cause a compiler error. Jeśli Metoda asynchroniczna nie używa operatora await, aby oznaczyć punkt zawieszenia, metoda jest wykonywana jako metoda synchroniczna, pomimo modyfikatora async.If an async method doesn't use an await operator to mark a suspension point, the method executes as a synchronous method does, despite the async modifier. Kompilator generuje ostrzeżenia dla takich metod.The compiler issues a warning for such methods.

async i await są kontekstowymi słowami kluczowymi.async and await are contextual keywords. Aby uzyskać więcej informacji i przykładów, zobacz następujący temat:For more information and examples, see the following topics:

Typy zwracane i parametryReturn types and parameters

Metoda async zwykle zwraca Task lub Task<TResult>.An async method typically returns a Task or a Task<TResult>. Wewnątrz metody asynchronicznej do zadania, które jest zwracane z wywołania innej metody asynchronicznej, jest stosowany operator await.Inside an async method, an await operator is applied to a task that's returned from a call to another async method.

Należy określić Task<TResult> jako typ zwracany, jeśli metoda zawiera instrukcję return , która określa operand typu TResult.You specify Task<TResult> as the return type if the method contains a return statement that specifies an operand of type TResult.

Użyj Task jako zwracanego typu, jeśli metoda nie ma instrukcji return lub zawiera instrukcję return, która nie zwraca operandu.You use Task as the return type if the method has no return statement or has a return statement that doesn't return an operand.

Począwszy od C# 7,0, można również określić dowolny inny zwracany typ, pod warunkiem, że typ zawiera metodę GetAwaiter.Starting with C# 7.0, you can also specify any other return type, provided that the type includes a GetAwaiter method. Przykładem takiego typu jest ValueTask<TResult>.ValueTask<TResult> is an example of such a type. Jest on dostępny w pakiecie NuGet System. Threading. Tasks. Extension .It is available in the System.Threading.Tasks.Extension NuGet package.

Poniższy przykład pokazuje, jak zadeklarować i wywołać metodę, która zwraca Task<TResult> lub Task:The following example shows how you declare and call a method that returns a Task<TResult> or a Task:

// Signature specifies Task<TResult>
async Task<int> GetTaskOfTResultAsync()
{
    int hours = 0;
    await Task.Delay(0);
    // Return statement specifies an integer result.
    return hours;
}

// Calls to GetTaskOfTResultAsync
Task<int> returnedTaskTResult = GetTaskOfTResultAsync();
int intResult = await returnedTaskTResult;
// or, in a single statement
int intResult = await GetTaskOfTResultAsync();

// Signature specifies Task
async Task GetTaskAsync()
{
    await Task.Delay(0);
    // The method has no return statement.
}

// Calls to GetTaskAsync
Task returnedTask = GetTaskAsync();
await returnedTask;
// or, in a single statement
await GetTaskAsync();

Każde zwracane zadanie reprezentuje zadanie pracy w toku.Each returned task represents ongoing work. Zadanie zawiera informacje o stanie procesu asynchronicznego i, ostatecznie, albo ostatecznego wyniku procesu lub wyjątku, który zgłasza proces, jeśli się nie powiedzie.A task encapsulates information about the state of the asynchronous process and, eventually, either the final result from the process or the exception that the process raises if it doesn't succeed.

Metoda asynchroniczna może również mieć void zwracanego typu.An async method can also have a void return type. Ten typ zwracany jest używany głównie do definiowania programów obsługi zdarzeń, w których wymagany jest void zwracany typ.This return type is used primarily to define event handlers, where a void return type is required. Programy async obsługi zdarzeń często służą jako punkt wejścia dla programów async.Async event handlers often serve as the starting point for async programs.

Nie można oczekiwać metody asynchronicznej, która ma void typ zwracany, a obiekt wywołujący metodę zwracającą wartość void nie może przechwycić żadnych wyjątków zgłaszanych przez metodę.An async method that has a void return type can't be awaited, and the caller of a void-returning method can't catch any exceptions that the method throws.

Metoda async nie może deklarować parametrów in, ref ani out , ale metoda może wywoływać metody, które mają takie parametry.An async method can't declare in, ref or out parameters, but the method can call methods that have such parameters. Podobnie Metoda asynchroniczna nie może zwracać wartości przez odwołanie, chociaż może wywoływać metody z ref zwracanymi wartościami.Similarly, an async method can't return a value by reference, although it can call methods with ref return values.

Aby uzyskać więcej informacji i przykładów, zobacz asynchroniczne typy zwracaneC#().For more information and examples, see Async Return Types (C#). Aby uzyskać więcej informacji o sposobie przechwytywania wyjątków w metodach asynchronicznych, zobacz try-catch.For more information about how to catch exceptions in async methods, see try-catch.

Asynchroniczne interfejsy API w programowaniu środowisko wykonawcze systemu Windows mają jeden z następujących typów zwracanych, które są podobne do zadań:Asynchronous APIs in Windows Runtime programming have one of the following return types, which are similar to tasks:

Konwencja nazewnictwaNaming convention

Zgodnie z Konwencją metody, które zwracają powszechnie oczekiwane typy (np. Task, Task<T>, ValueTask``ValueTask<T>) powinny mieć nazwy kończące się na "Async".By convention, methods that return commonly awaitable types (e.g. Task, Task<T>, ValueTask, ValueTask<T>) should have names that end with "Async". Metody, które uruchamiają operację asynchroniczną, ale nie zwracają typu oczekującego, nie powinny mieć nazw kończących się na "Async", ale mogą zaczynać się od "BEGIN", "Start" lub innego zlecenia, aby zasugerować, że ta metoda nie zwraca lub nie generuje wyniku operacji.Methods that start an asynchronous operation but do not return an awaitable type should not have names that end with "Async", but may start with "Begin", "Start", or some other verb to suggest this method does not return or throw the result of the operation.

Można zignorować konwencję, gdy zdarzenie, klasa bazowa lub kontrakt interfejsu sugeruje inną nazwę.You can ignore the convention where an event, base class, or interface contract suggests a different name. Na przykład nie należy zmieniać nazw często używanych procedur obsługi zdarzeń, takich jak Button1_Click.For example, you shouldn't rename common event handlers, such as Button1_Click.

Tematy pokrewne i przykłady (Visual Studio)Related topics and samples (Visual Studio)

TytułTitle OpisDescription PrzykładSample
Przewodnik: uzyskiwanie dostępu do sieci Web za pomocą AsyncC#i Await ()Walkthrough: Accessing the Web by Using async and await (C#) Przedstawia, w jaki sposób konwertować synchroniczne rozwiązanie WPF do asynchronicznego rozwiązania WPF.Shows how to convert a synchronous WPF solution to an asynchronous WPF solution. Ta aplikacja pobiera szereg witryn sieci Web.The application downloads a series of websites. Przykład asynchroniczny: uzyskiwanie dostępu do przewodnika dla sieci WebAsync Sample: Accessing the Web Walkthrough
Jak rozłożyć Instruktaż asynchroniczny za pomocą metody Task. WhenAllC#()How to extend the async walkthrough by using Task.WhenAll (C#) Dodaje Task.WhenAll do poprzedniego przewodnika.Adds Task.WhenAll to the previous walkthrough. Użycie WhenAll uruchamia wszystkie pliki do pobrania w tym samym czasie.The use of WhenAll starts all the downloads at the same time.
Jak wykonać równolegle wiele żądań sieci Web za pomocą Async i Await (C#)How to make multiple web requests in parallel by using async and await (C#) Ilustruje, jak uruchomić kilka zadań w tym samym czasie.Demonstrates how to start several tasks at the same time. Przykład Async: równoległe wykonywanie wielu żądań sieci WebAsync Sample: Make Multiple Web Requests in Parallel
Asynchroniczne typy zwracane (C#)Async Return Types (C#) Ilustruje typy zwracane przez metody async i wyjaśnia, kiedy poszczególne typy są odpowiednie.Illustrates the types that async methods can return and explains when each type is appropriate.
Przepływ sterowania w programach asynchronicznychC#()Control Flow in Async Programs (C#) Śledzi szczegółowo przepływ sterowania w serii wyrażeń await w programie asynchronicznym.Traces in detail the flow of control through a succession of await expressions in an asynchronous program. Przykład asynchroniczny: przepływ sterowania w programach asynchronicznychAsync Sample: Control Flow in Async Programs
Dostrajanie aplikacji asynchronicznej (C#)Fine-Tuning Your Async Application (C#) Przedstawia, w jaki sposób dodać następujące funkcje do rozwiązania async:Shows how to add the following functionality to your async solution:

- anulować zadanie asynchroniczne lub listę zadańC#()- Cancel an Async Task or a List of Tasks (C#)
- anulować zadania asynchroniczne po upływie czasu (C#)- Cancel Async Tasks after a Period of Time (C#)
- anulować pozostałe zadania asynchroniczne po zakończeniu jednegoC#()- Cancel Remaining Async Tasks after One Is Complete (C#)
- uruchomić wiele zadań asynchronicznych i przetworzyć je wC#miarę ich ukończenia ()- Start Multiple Async Tasks and Process Them As They Complete (C#)
Próbka asynchroniczna: dostrajanie aplikacjiAsync Sample: Fine Tuning Your Application
Obsługa współużytkowania wątkowości w aplikacjach asynchronicznychC#()Handling Reentrancy in Async Apps (C#) Pokazuje, jak obsługiwać przypadki, w których aktywna operacja asynchroniczna jest uruchamiana ponownie, gdy jest uruchomiona.Shows how to handle cases in which an active asynchronous operation is restarted while it's running.
WhenAny: mostkowanie między .NET Framework i środowisko wykonawcze systemu WindowsWhenAny: Bridging between the .NET Framework and the Windows Runtime Pokazuje, jak połączyć typy zadań w .NET Framework i IAsyncOperations w środowisko wykonawcze systemu Windows, aby można było używać WhenAny z metodą środowisko wykonawcze systemu Windows.Shows how to bridge between Task types in the .NET Framework and IAsyncOperations in the Windows Runtime so that you can use WhenAny with a Windows Runtime method. Próbka asynchroniczna: mostkowanie między programami .NET i środowisko wykonawcze systemu Windows (AsTask i WhenAny)Async Sample: Bridging between .NET and Windows Runtime (AsTask and WhenAny)
Anulowanie asynchroniczne: łączenie platformy .NET Framework ze środowiskiem wykonawczym systemu WindowsAsync Cancellation: Bridging between the .NET Framework and the Windows Runtime Pokazuje, jak połączyć typy zadań w .NET Framework i IAsyncOperations w środowisko wykonawcze systemu Windows, aby można było używać CancellationTokenSource z metodą środowisko wykonawcze systemu Windows.Shows how to bridge between Task types in the .NET Framework and IAsyncOperations in the Windows Runtime so that you can use CancellationTokenSource with a Windows Runtime method. Próbka asynchroniczna: mostkowanie między programami .NET i środowisko wykonawcze systemu Windows (anulowanie & AsTask)Async Sample: Bridging between .NET and Windows Runtime (AsTask & Cancellation)
Używanie Async na potrzeby dostępu doC#plików ()Using Async for File Access (C#) Wyświetla listę korzyści wynikających ze stosowania słów kluczowych async i await przy uzyskiwaniu dostępu do plików.Lists and demonstrates the benefits of using async and await to access files.
Wzorzec asynchroniczny oparty na zadaniach (TAP)Task-based Asynchronous Pattern (TAP) Opisano nowy wzorzec asynchronii w .NET Framework.Describes a new pattern for asynchrony in the .NET Framework. Wzorzec jest oparty na typach Task i Task<TResult>.The pattern is based on the Task and Task<TResult> types.
Asynchroniczne wideo w kanale 9Async Videos on Channel 9 Oferuje łącza do różnych plików wideo dotyczących programowania asynchronicznego.Provides links to a variety of videos about async programming.

Pełny przykładComplete example

Poniższy kod jest plikiem MainWindow.XAML.cs z aplikacji WPF, którą omówiono w tym artykule.The following code is the MainWindow.xaml.cs file from the WPF application that this article discusses. Możesz pobrać przykład z przykładu asynchronicznego: przykład z "programowania asynchronicznego z Async i await".You can download the sample from Async Sample: Example from "Asynchronous Programming with Async and Await".

using System;
using System.Threading.Tasks;
using System.Windows;

// Add a using directive and a reference for System.Net.Http;
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it.
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately.
            //Task<int> getLengthTask = AccessTheWebAsync();
            //// You can do independent work here.
            //int contentLength = await getLengthTask;

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                $"\r\nLength of the downloaded string: {contentLength}.\r\n";
        }


        // Three things to note in the signature:
        //  - The method has an async modifier. 
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer.
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            var client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("https://docs.microsoft.com/dotnet");

            // You can do work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork();

            // The await operator suspends AccessTheWebAsync.
            //  - AccessTheWebAsync can't continue until getStringTask is complete.
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync.
            //  - Control resumes here when getStringTask is complete. 
            //  - The await operator then retrieves the string result from getStringTask.
            string urlContents = await getStringTask;

            // The return statement specifies an integer result.
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value.
            return urlContents.Length;
        }

        void DoIndependentWork()
        {
            resultsTextBox.Text += "\r\nWorking . . . . . . .\r\n";
        }
    }
}

// Sample Output:

// Working . . . . . . .

// Length of the downloaded string: 41564.

Zobacz takżeSee also