asynchroon (C#-verwijzing)
Gebruik de async
wijzigingsfunctie om op te geven dat een methode, lambda-expressie of anonieme methode asynchroon is. Als u deze wijzigingsfunctie gebruikt voor een methode of expressie, wordt deze een asynchrone methode genoemd. In het volgende voorbeeld wordt een asynchrone methode met de naam ExampleMethodAsync
gedefinieerd:
public async Task<int> ExampleMethodAsync()
{
//...
}
Als u geen kennis hebt van asynchroon programmeren of niet begrijpt hoe een asynchrone methode gebruikmaakt van de await
operator om mogelijk langlopend werk uit te voeren zonder de thread van de aanroeper te blokkeren, leest u de inleiding in Asynchrone programmering met asynchroon en wacht u af. De volgende code wordt gevonden in een asynchrone methode en roept de methode aan HttpClient.GetStringAsync :
string contents = await httpClient.GetStringAsync(requestUrl);
Een asynchrone methode wordt synchroon uitgevoerd totdat deze de eerste await
expressie bereikt, waarna de methode wordt onderbroken totdat de wachtende taak is voltooid. Ondertussen keert het besturingselement terug naar de aanroeper van de methode, zoals in het voorbeeld in de volgende sectie wordt weergegeven.
Als de methode die door het async
trefwoord wordt gewijzigd geen expressie of instructie bevat await
, wordt de methode synchroon uitgevoerd. Een compilerwaarschuwing waarschuwt u voor asynchrone methoden die geen instructies bevatten await
, omdat deze situatie een fout kan aangeven. Zie Compilerwaarschuwing (niveau 1) CS4014.
Het async
trefwoord is contextueel omdat het alleen een trefwoord is wanneer een methode, een lambda-expressie of een anonieme methode wordt gewijzigd. In alle andere contexten wordt deze geïnterpreteerd als een id.
Opmerking
In het volgende voorbeeld ziet u de structuur en de controlestroom tussen een asynchrone gebeurtenishandler en StartButton_Click
een asynchrone methode. ExampleMethodAsync
Het resultaat van de asynchrone methode is het aantal tekens van een webpagina. De code is geschikt voor een WPF-app (Windows Presentation Foundation) of Windows Store-app die u maakt in Visual Studio; zie de codeopmerkingen voor het instellen van de app.
U kunt deze code uitvoeren in Visual Studio als een WPF-app (Windows Presentation Foundation) of een Windows Store-app. U hebt een besturingselement Knop met de naam StartButton
en een tekstvak met de naam ResultsTextBox
nodig. Vergeet niet om de namen en handler zo in te stellen dat u iets als volgt hebt:
<Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top" Width="75"
Click="StartButton_Click" Name="StartButton"/>
<TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap"
Text="<Enter a URL>" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/>
De code uitvoeren als een WPF-app:
- Plak deze code in de
MainWindow
klasse in MainWindow.xaml.cs. - Voeg een verwijzing toe naar System.Net.Http.
- Voeg een
using
richtlijn toe voor System.Net.Http.
De code uitvoeren als een Windows Store-app:
- Plak deze code in de
MainPage
klasse in MainPage.xaml.cs. - Voeg
using
instructies toe voor System.Net.Http en System.Threading.Tasks.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
// ExampleMethodAsync returns a Task<int>, which means that the method
// eventually produces an int result. However, ExampleMethodAsync returns
// the Task<int> value as soon as it reaches an await.
ResultsTextBox.Text += "\n";
try
{
int length = await ExampleMethodAsync();
// Note that you could put "await ExampleMethodAsync()" in the next line where
// "length" is, but due to when '+=' fetches the value of ResultsTextBox, you
// would not see the global side effect of ExampleMethodAsync setting the text.
ResultsTextBox.Text += String.Format("Length: {0:N0}\n", length);
}
catch (Exception)
{
// Process the exception if one occurs.
}
}
public async Task<int> ExampleMethodAsync()
{
var httpClient = new HttpClient();
int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length;
ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";
// After the following return statement, any method that's awaiting
// ExampleMethodAsync (in this case, StartButton_Click) can get the
// integer result.
return exampleInt;
}
// The example displays the following output:
// Preparing to finish ExampleMethodAsync.
// Length: 53292
Belangrijk
Zie Asynchrone programmering met asynchroon programmeren en wachten op een taak voor meer informatie over taken en de code die wordt uitgevoerd. Zie Asynchrone taken verwerken wanneer ze zijn voltooid (C#) voor een volledig consolevoorbeeld waarin vergelijkbare elementen worden gebruikt.
Retourtypen
Een asynchrone methode kan de volgende retourtypen hebben:
- Task
- Task<TResult>
- void.
async void
methoden worden over het algemeen afgeraden voor andere code dan gebeurtenis-handlers, omdat aanroepers deze methoden nietawait
kunnen gebruiken en een ander mechanisme moeten implementeren om geslaagde voltooiings- of foutvoorwaarden te rapporteren. - Elk type dat een toegankelijke
GetAwaiter
methode heeft. HetSystem.Threading.Tasks.ValueTask<TResult>
type is een dergelijke implementatie. Het is beschikbaar door het NuGet-pakketSystem.Threading.Tasks.Extensions
toe te voegen.
De asynchrone methode kan geen parameters in, verw of out declareren, noch kan deze een retourwaarde voor verwijzingen hebben, maar kan methoden aanroepen die dergelijke parameters hebben.
U geeft Task<TResult>
op als het retourtype van een asynchrone methode als de retourinstructie van de methode een operand van het type TResult
opgeeft. U gebruikt Task
als er geen zinvolle waarde wordt geretourneerd wanneer de methode is voltooid. Dat wil gezegd: een aanroep van de methode retourneert een Task
, maar wanneer de Task
bewerking is voltooid, wordt elke await
expressie die wacht op de Task
evaluatie void
.
U gebruikt het void
retourtype voornamelijk om gebeurtenis-handlers te definiëren, waarvoor dat retourtype is vereist. De aanroeper van een retourneert asynchrone void
methode kan deze niet wachten en kan geen uitzonderingen vangen die de methode genereert.
U retourneert een ander type, meestal een waardetype, dat een GetAwaiter
methode heeft om geheugentoewijzingen in prestatiekritieke secties met code te minimaliseren.
Zie Asynchrone retourtypen voor meer informatie en voorbeelden.