Sobes.tech
Middle

Come funziona il meccanismo async/await in C#?

sobes.tech AI

Risposta dell'AI

Il meccanismo async/await consente di scrivere codice asincrono che sembra sincrono.

  1. Parola chiave async: Contrassegna un metodo come asincrono. Tale metodo può contenere l'istruzione await.
  2. Parola chiave await: Viene usata prima di chiamare un'operazione asincrona (di solito un metodo che restituisce Task o Task<T>). Quando l'esecuzione raggiunge await, il controllo viene restituito al metodo chiamante, e il thread liberato può eseguire un'altra attività.
  3. Task / Task<T>: Rappresenta una promessa di completamento di un'operazione asincrona e del suo risultato (per Task<T>). await "attende" il completamento di questa "promessa".
  4. Macchina a stati: Il compilatore trasforma il metodo asincrono in una macchina a stati. Questa macchina conserva lo stato del metodo al raggiungimento di await.
  5. Continuazione: Quando il task atteso si completa, l'ambiente di esecuzione pianifica l'esecuzione della parte restante del metodo asincrono (la continuazione) su un thread del pool o nello stesso contesto di sincronizzazione se catturato.
  6. Ritorno del controllo: Dopo aver completato l'operazione asincrona, il controllo ritorna al punto dopo await, e l'esecuzione del metodo continua con lo stato salvato.
// Metodo asincrono
async Task<int> GetLengthAsync(string url)
{
    // Creare client HTTP
    using var client = new HttpClient(); 
    // Effettuare richiesta asincrona all'URL
    // Await aspetta la conclusione della richiesta senza bloccare il thread
    string content = await client.GetStringAsync(url); 
    // La continuazione si esegue dopo aver ottenuto il contenuto
    return content.Length; 
}

// Uso del metodo asincrono
async void Button_Click(object sender, EventArgs e)
{
    // Await aspetta che GetLengthAsync finisca
    // Il thread UI non viene bloccato
    int length = await GetLengthAsync("https://example.com"); 
    // Aggiornare elemento UI
    Label1.Text = $"Lunghezza del contenuto: {length}"; 
}