Sobes.tech
Middle

Πώς λειτουργεί ο μηχανισμός async/await στη C#;

sobes.tech AI

Απάντηση από AI

Ο μηχανισμός async/await επιτρέπει τη συγγραφή ασύγχρονου κώδικα που φαίνεται σαν συγχρονικός.

  1. Λέξη-κλειδί async: Σημαδεύει μια μέθοδο ως ασύγχρονη. Μια τέτοια μέθοδος μπορεί να περιέχει την εντολή await.
  2. Λέξη-κλειδί await: Χρησιμοποιείται πριν από την κλήση μιας ασύγχρονης λειτουργίας (συνήθως μια μέθοδος που επιστρέφει Task ή Task<T>). Όταν η εκτέλεση φτάσει στο await, ο έλεγχος επιστρέφει στη μέθοδο που την κάλεσε, και το ελεύθερο νήμα μπορεί να εκτελέσει άλλη εργασία.
  3. Task / Task<T>: Αντιπροσωπεύει μια υπόσχεση ολοκλήρωσης μιας ασύγχρονης λειτουργίας και το αποτέλεσμα της (για το Task<T>). Το await "περιμένει" την ολοκλήρωση αυτής της "υπόσχεσης".
  4. Μηχανή καταστάσεων: Ο μεταγλωττιστής μετατρέπει τη μέθοδο async σε μια μηχανή καταστάσεων. Αυτή η μηχανή διατηρεί την κατάσταση της μεθόδου κατά την άφιξη στο await.
  5. Συνέχεια: Όταν η αναμενόμενη εργασία ολοκληρωθεί, το περιβάλλον εκτέλεσης προγραμματίζει την εκτέλεση του υπόλοιπου μέρους της ασύγχρονης μεθόδου (της συνέχειας) σε ένα νήμα από το pool νημάτων ή στο ίδιο πλαίσιο συγχρονισμού, αν αυτό έχει πιαστεί.
  6. Επιστροφή ελέγχου: Μετά την ολοκλήρωση της ασύγχρονης λειτουργίας, ο έλεγχος επιστρέφει στο σημείο μετά το await, και η εκτέλεση της μεθόδου συνεχίζεται με την αποθηκευμένη κατάσταση.
// Ασύγχρονη μέθοδος
async Task<int> GetLengthAsync(string url)
{
    // Δημιουργία HTTP πελάτη
    using var client = new HttpClient(); 
    // Εκτέλεση ασύγχρονης αίτησης στο URL
    // Το await περιμένει την ολοκλήρωση της αίτησης χωρίς να μπλοκάρει το νήμα
    string content = await client.GetStringAsync(url); 
    // Η συνέχεια εκτελείται μετά την λήψη του περιεχομένου
    return content.Length; 
}

// Χρήση της ασύγχρονης μεθόδου
async void Button_Click(object sender, EventArgs e)
{
    // Το await περιμένει να τελειώσει το GetLengthAsync
    // Το νήμα UI δεν μπλοκάρεται
    int length = await GetLengthAsync("https://example.com"); 
    // Ενημέρωση στοιχείου UI
    Label1.Text = $"Μήκος περιεχομένου: {length}"; 
}