async (Riferimenti per C#)
Usare il modificatore async
per specificare che un metodo, un'espressione lambda o un metodo anonimo sia asincrono. Se si usa questo modificatore in un metodo o in un'espressione, viene indicato come metodo asincrono. L'esempio seguente definisce un metodo asincrono denominato ExampleMethodAsync
:
public async Task<int> ExampleMethodAsync()
{
//...
}
Se non si ha esperienza di programmazione asincrona o non si sa in che modo un metodo asincrono usa l'operatore await
per eseguire attività potenzialmente prolungate senza bloccare il thread del chiamante, leggere l'introduzione in Programmazione asincrona con async e await. Il codice seguente si trova all'interno di un metodo asincrono e chiama il metodo HttpClient.GetStringAsync:
string contents = await httpClient.GetStringAsync(requestUrl);
Un metodo asincrono viene eseguito in modo sincrono finché non raggiunge la prima espressione await
. A quel punto, il metodo viene sospeso fino al completamento dell'attività attesa. Nel frattempo il controllo torna al chiamante del metodo, come illustrato nell'esempio della sezione successiva.
Il metodo modificato dalla parola chiave async
viene eseguito in modo sincrono se non contiene un'espressione o un'istruzione await
. Un avviso del compilatore segnala eventuali metodi asincroni che non contengono istruzioni await
, perché questa situazione potrebbe indicare un errore. Vedere Avviso del compilatore (livello 1) CS4014.
La parola chiave async
è contestuale, in quanto è una parola chiave solo quando modifica un metodo, un'espressione lambda o un metodo anonimo. In tutti gli altri contesti, viene interpretato come identificatore.
Esempio
Nell'esempio seguente vengono illustrati la struttura e il flusso di controllo tra un gestore eventi asincrono, StartButton_Click
, e un metodo asincrono, ExampleMethodAsync
. Il risultato ottenuto dal metodo asincrono è il numero di caratteri di una pagina Web. Il codice è adatto per un'applicazione Windows Presentation Foundation (WPF) o un'app di Windows Store creata in Visual Studio. Vedere i commenti del codice per l'installazione dell'applicazione.
È possibile eseguire questo codice in Visual Studio come un'app Windows Presentation Foundation (WPF) o un'app di Windows Store. Sono necessari un controllo Button denominato StartButton
e un controllo Textbox denominato ResultsTextBox
. Ricordare di impostare i nomi e il gestore in modo da ottenere codice simile al seguente:
<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"/>
Per eseguire il codice come app WPF:
- Incollare il codice nella classe
MainWindow
in MainWindow.xaml.cs. - Aggiungere un riferimento a System.Net.Http.
- Aggiungere una direttiva
using
per System.Net.Http.
Per eseguire il codice come app di Windows Store:
- Incollare questo codice nella classe
MainPage
in MainPage.xaml.cs. - Aggiungere
using
direttive per System.Net.Http e 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
Importante
Per altre informazioni sulle attività e sul codice eseguito in attesa di un'attività, vedere Programmazione asincrona con async e await. Per un esempio completo della console che usa elementi simili, vedere Elaborare le attività asincrone non appena vengono completate (C#).
Tipi restituiti
Un metodo asincrono può avere i tipi restituiti seguenti:
- Task
- Task<TResult>
- void. I metodi
async void
sono in genere sconsigliati per il codice diverso dai gestori eventi perché i chiamanti non possono usareawait
per questi metodi e devono implementare un meccanismo diverso per segnalare il completamento corretto o condizioni di errore. - Qualsiasi tipo dotato di un metodo accessibile
GetAwaiter
. Il tipoSystem.Threading.Tasks.ValueTask<TResult>
è una di queste implementazioni ed è disponibile aggiungendo il pacchetto NuGetSystem.Threading.Tasks.Extensions
.
Un metodo asincrono non può dichiarare parametri in, ref o out e nemmeno avere un valore di riferimento restituito , ma può chiamare metodi con tali parametri.
Specificare Task<TResult>
come tipo restituito di un metodo asincrono se l'istruzione return del metodo specifica un operando di tipo TResult
. Utilizzare Task
se non viene restituito alcun valore significativo al completamento del metodo. Ciò significa che una chiamata al metodo restituisce Task
, ma al completamento di Task
, qualsiasi espressione await
in attesa di Task
restituisce void
.
Utilizzare il tipo restituito void
principalmente per definire gestori eventi, che richiedono tale tipo restituito. Il chiamante di un metodo asincrono che restituisce void
non può attendere il metodo e non può acquisire eccezioni generate dal metodo.
Viene restituito un altro tipo, in genere un tipo valore, che ha un metodo GetAwaiter
per ridurre al minimo le allocazioni di memoria nelle sezioni di codice critiche per le prestazioni.
Per altre informazioni ed esempi, vedere Tipi restituiti asincroni.