Asynchronous programming – Async & Await – P2

3 min read

Ở phần trước, ta đã nói về việc lập trình đồng bộ trong một ví dụ đơn giản là làm bữa ăn sáng. Phần 2 nãy, sẽ giới thiệu về cách áp dụng lập trình bất đồng bộ vào ví dụ trên.

2. Ví dụ

2.2. Lập trình bất đồng bộ

Đoạn code trước đó ở mục 2.1 được thực hiện không tốt: xây dựng code đồng bộ để thực hiện các hành động bất đồng bộ. Như đã đề cập trên, mã này chặn luồng thực thi, nó sẽ không thực hiện bất kỳ công việc nào khác. Giống như là bạn nhìn vào lò nướng sau khi đặt bánh mì vào đó. Bạn sẽ bỏ qua bất kỳ ai nói chuyện với bạn cho đến khi bánh mì nướng xong.

Hãy bắt đầu bằng cách cập nhật code này sao cho luồng không bị chặn trong khi các tác vụ đang chạy. Từ khóa await cung cấp một cách không chặn để bắt đầu một tác vụ, sau đó tiếp tục thực thi khi tác vụ đó hoàn thành. Một phiên bản bất đồng bộ đơn giản của mã làm bữa sáng sẽ trông giống như đoạn mã sau:

static async Task Main(string[] args)
{
    Coffee cup = PourCoffee();
    Console.WriteLine("Cà phê sẵn sàng");

    Egg eggs = await FryEggsAsync(2);
    Console.WriteLine("Trứng sẵn sàng");

    Bacon bacon = await FryBaconAsync(3);
    Console.WriteLine("Thịt xông khói sẵn sàng");

    Toast toast = await ToastBreadAsync(2);
    ApplyButter(toast);
    ApplyJam(toast);
    Console.WriteLine("Bánh mì nướng sẵn sàng");

    Juice oj = PourOJ();
    Console.WriteLine("Nước cam sẵn sàng");
    Console.WriteLine("Bữa sáng sẵn sàng!");
}

Đoạn mã này không chặn trong khi trứng hoặc thịt xông khói đang nấu. Tuy nhiên, đoạn mã này không bắt đầu bất kỳ tác vụ nào khác. Bạn vẫn sẽ đặt bánh mì vào lò nướng và nhìn vào nó cho đến khi bánh mì nướng xong. Nhưng ít nhất, bạn sẽ phản ứng với bất kỳ ai muốn chú ý của bạn. Trong một nhà hàng nơi có nhiều đơn hàng được đặt, đầu bếp có thể bắt đầu một bữa sáng khác trong khi bữa đầu tiên đang nấu.

Tuy đoạn code trên đã sử dụng lập trình bất đồng bộ. Những do vẫn chưa tận dụng được một số tính năng chính của lập trình bất động bộ. Do đó, tổng thời gian gần giống như phiên bản ban đầu.

2.3 Bắt đầu các tác vụ song song

Trong nhiều tình huống, bạn muốn bắt đầu một số tác vụ độc lập ngay lập tức. Sau đó, khi mỗi tác vụ hoàn thành, bạn có thể tiếp tục công việc khác đang chờ. Trong ví dụ về bữa sáng, đó là cách bạn hoàn thành bữa sáng nhanh hơn. Bạn cũng hoàn thành mọi thứ gần như cùng một lúc. Bạn sẽ có một bữa sáng nóng hổi.

Các lớp System.Threading.Tasks.Task và các lớp liên quan là những lớp bạn có thể sử dụng để suy luận về các tác vụ đang tiến hành. Điều này cho phép bạn viết mã giống với cách bạn tạo bữa sáng. Bạn sẽ bắt đầu nấu trứng, thịt xông khói và bánh mì nướng cùng một lúc. Khi mỗi tác vụ cần hành động, bạn sẽ chuyển sự chú ý của mình sang tác vụ đó, thực hiện công việc tiếp theo, sau đó chờ đợi điều gì đó khác cần sự chú ý của bạn.

Coffee cup = PourCoffee();
Console.WriteLine("Cà phê sẵn sàng");

Task<Egg> eggsTask = FryEggsAsync(2);
Task<Bacon> baconTask = FryBaconAsync(3);
Task<Toast> toastTask = ToastBreadAsync(2);

Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("Bánh mì nướng sẵn sàng");
Juice oj = PourOJ();
Console.WriteLine("Nước cam sẵn sàng");

Egg eggs = await eggsTask;
Console.WriteLine("Trứng sẵn sàng");
Bacon bacon = await baconTask;
Console.WriteLine("Thịt xông khói sẵn sàng");

Console.WriteLine("Bữa sáng sẵn sàng!");

Bữa sáng được chuẩn bị bất đồng bộ mất khoảng 20 phút, sự tiết kiệm thời gian này là do một số tác vụ chạy song song.

Còn một phần nữa, nó về làm sao để tối ưu hóa, tiết kiêm thời gian hơn nữa. Mọi người hay cùng theo dõi nhé!!!

Tài liệu tham khảo: https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/

Avatar photo

One Reply to “Asynchronous programming – Async & Await – P2”

Leave a Reply

Your email address will not be published. Required fields are marked *