Ας εξηγήσουμε τον ασύγχρονο προγραμματισμό με async και await στην C# με έναν απλό και κατανοητό τρόπο.
Τι είναι ο ασύγχρονος προγραμματισμός;
Φαντάσου ότι μαγειρεύεις στο σπίτι και ταυτόχρονα περιμένεις να φορτώσει ένα βίντεο στον υπολογιστή σου. Αντί να περιμένεις να φορτώσει το βίντεο και να μην κάνεις τίποτα άλλο, μπορείς να συνεχίσεις να μαγειρεύεις και να ελέγχεις από καιρό σε καιρό αν το βίντεο έχει φορτώσει. Αυτό είναι ο ασύγχρονος προγραμματισμός: κάνεις άλλα πράγματα ενώ περιμένεις κάτι να ολοκληρωθεί.
Πώς λειτουργεί το async και await;
async: Λέει στον υπολογιστή ότι μια μέθοδος μπορεί να τρέξει ασύγχρονα, δηλαδή δεν θα μπλοκάρει το υπόλοιπο πρόγραμμα όσο εκτελείται.
await: Λέει στον υπολογιστή να περιμένει το αποτέλεσμα μιας ασύγχρονης λειτουργίας πριν συνεχίσει να εκτελεί τον υπόλοιπο κώδικα.
Παράδειγμα με απλά λόγια:
Ας πούμε ότι θέλουμε να κατεβάσουμε μια εικόνα από το διαδίκτυο και να την εμφανίσουμε στην οθόνη.
Χωρίς ασύγχρονο προγραμματισμό:
Αν δεν χρησιμοποιήσουμε async και await, το πρόγραμμα θα περιμένει να ολοκληρωθεί η λήψη της εικόνας πριν συνεχίσει να κάνει οτιδήποτε άλλο.
public void DownloadImage()
{
var image = DownloadImageFromInternet(); // Αυτή η λειτουργία μπορεί να πάρει χρόνο
DisplayImage(image);
}
Με ασύγχρονο προγραμματισμό:
Χρησιμοποιώντας async
και await
, το πρόγραμμα μπορεί να κάνει άλλες εργασίες όσο περιμένει να κατεβεί η εικόνα.
public async Task DownloadImageAsync()
{
var image = await DownloadImageFromInternetAsync(); // Περιμένουμε την λήψη της εικόνας ασύγχρονα
DisplayImage(image);
}
Πλήρες παράδειγμα σε C#
Ας δούμε ένα παράδειγμα όπου θα κατεβάσουμε περιεχόμενο από έναν ιστότοπο και θα το εμφανίσουμε στην οθόνη.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Ξεκινάει η λήψη δεδομένων...");
string result = await DownloadContentAsync("https://www.example.com");
Console.WriteLine("Η λήψη ολοκληρώθηκε.");
Console.WriteLine(result);
}
static async Task<string> DownloadContentAsync(string url)
{
using (HttpClient client = new HttpClient())
{
string content = await client.GetStringAsync(url);
return content;
}
}
}
Τι συμβαίνει εδώ:
async Task Main(string[] args)
:- Κάνουμε την κύρια μέθοδο ασύγχρονη ώστε να μπορούμε να χρησιμοποιήσουμε
await
μέσα σε αυτή.
- Κάνουμε την κύρια μέθοδο ασύγχρονη ώστε να μπορούμε να χρησιμοποιήσουμε
Console.WriteLine("Ξεκινάει η λήψη δεδομένων...");
:- Εμφανίζουμε ένα μήνυμα ότι η λήψη ξεκινάει.
string result = await DownloadContentAsync("https://www.example.com");
:- Καλούμε την ασύγχρονη μέθοδο
DownloadContentAsync
και περιμένουμε το αποτέλεσμά της.
- Καλούμε την ασύγχρονη μέθοδο
Console.WriteLine("Η λήψη ολοκληρώθηκε.");
:- Εμφανίζουμε ένα μήνυμα ότι η λήψη ολοκληρώθηκε.
Console.WriteLine(result);
:- Εμφανίζουμε το περιεχόμενο που κατεβάσαμε.
static async Task<string> DownloadContentAsync(string url)
:- Ορίζουμε μια ασύγχρονη μέθοδο για να κατεβάσουμε το περιεχόμενο από μια διεύθυνση URL.
string content = await client.GetStringAsync(url);
:- Χρησιμοποιούμε το
await
για να περιμένουμε την ολοκλήρωση της λήψης του περιεχομένου από τον ιστότοπο.
- Χρησιμοποιούμε το
Τι μάθαμε:
Με τον ασύγχρονο προγραμματισμό, μπορούμε να κάνουμε άλλες εργασίες ενώ περιμένουμε την ολοκλήρωση κάποιων λειτουργιών που μπορεί να πάρουν χρόνο. Αυτό κάνει το πρόγραμμά μας πιο αποδοτικό και ευέλικτο.
Ας δούμε μερικά παραδείγματα του ασύγχρονου προγραμματισμού με async
και await
στην C#. Αυτά τα παραδείγματα θα δείξουν διαφορετικές περιπτώσεις χρήσης της ασύγχρονης λειτουργικότητας.
1. Λήψη Περιεχομένου από Ιστότοπο
Ας δούμε πώς μπορούμε να κατεβάσουμε περιεχόμενο από έναν ιστότοπο ασύγχρονα και να το εμφανίσουμε στην οθόνη.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Ξεκινάει η λήψη δεδομένων...");
string content = await DownloadContentAsync("https://www.example.com");
Console.WriteLine("Η λήψη ολοκληρώθηκε.");
Console.WriteLine(content);
}
static async Task<string> DownloadContentAsync(string url)
{
using HttpClient client = new HttpClient();
string content = await client.GetStringAsync(url);
return content;
}
}
2. Ασύγχρονη Αναμονή σε Εφαρμογή Χρήστη
Ας υποθέσουμε ότι έχουμε μια εφαρμογή που εκτελεί μια μακροχρόνια εργασία και θέλουμε να δείξουμε μια ένδειξη φόρτωσης μέχρι να ολοκληρωθεί η εργασία.
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Η εργασία ξεκινάει...");
Task task = PerformLongRunningOperationAsync();
Console.WriteLine("Παρακαλώ περιμένετε, η εργασία βρίσκεται σε εξέλιξη...");
await task;
Console.WriteLine("Η εργασία ολοκληρώθηκε!");
}
static async Task PerformLongRunningOperationAsync()
{
await Task.Delay(5000); // Προσομοίωση μακροχρόνιας εργασίας (5 δευτερόλεπτα)
}
}
3. Χρήση Ασύγχρονης Λειτουργίας με Παράλληλη Εκτέλεση
Σε αυτό το παράδειγμα, θα καλέσουμε πολλές ασύγχρονες εργασίες ταυτόχρονα και θα περιμένουμε να ολοκληρωθούν όλες.
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Task[] tasks = new Task[]
{
PerformTaskAsync("Αποστολή 1", 3000),
PerformTaskAsync("Αποστολή 2", 2000),
PerformTaskAsync("Αποστολή 3", 1000)
};
Console.WriteLine("Αναμονή για ολοκλήρωση όλων των αποστολών...");
await Task.WhenAll(tasks);
Console.WriteLine("Όλες οι αποστολές ολοκληρώθηκαν!");
}
static async Task PerformTaskAsync(string taskName, int delay)
{
Console.WriteLine($"{taskName} ξεκινάει...");
await Task.Delay(delay);
Console.WriteLine($"{taskName} ολοκληρώθηκε.");
}
}
4. Ασύγχρονη Ανάγνωση και Εγγραφή Αρχείων
Αυτό το παράδειγμα δείχνει πώς μπορούμε να διαβάσουμε και να γράψουμε αρχεία ασύγχρονα.
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string filePath = "example.txt";
string contentToWrite = "Αυτό είναι ένα παράδειγμα περιεχομένου.";
// Γράφουμε στο αρχείο ασύγχρονα
await File.WriteAllTextAsync(filePath, contentToWrite);
Console.WriteLine("Η εγγραφή στο αρχείο ολοκληρώθηκε.");
// Διαβάζουμε από το αρχείο ασύγχρονα
string contentRead = await File.ReadAllTextAsync(filePath);
Console.WriteLine("Η ανάγνωση από το αρχείο ολοκληρώθηκε.");
Console.WriteLine("Περιεχόμενο αρχείου:");
Console.WriteLine(contentRead);
}
}
5. Ασύγχρονη Κλήση API με Χειρισμό Εξαιρέσεων
Ας δούμε πώς μπορούμε να κάνουμε μια κλήση σε ένα API και να χειριστούμε τυχόν σφάλματα.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
try
{
string apiUrl = "https://api.example.com/data";
string result = await FetchDataFromApiAsync(apiUrl);
Console.WriteLine("Λήψη δεδομένων ολοκληρώθηκε:");
Console.WriteLine(result);
}
catch (HttpRequestException e)
{
Console.WriteLine($"Σφάλμα κατά την κλήση του API: {e.Message}");
}
}
static async Task<string> FetchDataFromApiAsync(string url)
{
using HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode(); // Ελέγχουμε για αποτυχία
return await response.Content.ReadAsStringAsync();
}
}