Bắt đầu với lập trình không đồng bộ

Đã hoàn thành

Các nhà phát triển sử dụng các kỹ thuật lập trình không đồng bộ để tránh các nút cổ chai hiệu suất và tăng cường độ nhạy tổng thể của các ứng dụng của họ. Tuy nhiên, các kỹ thuật truyền thống để viết các ứng dụng không đồng bộ có thể phức tạp, làm cho chúng khó khăn để viết, gỡ lỗi và duy trì.

C# hỗ trợ phương pháp lập trình không đồng bộ đơn giản hóa tận dụng hỗ trợ không đồng bộ trong thời gian chạy .NET. Trình biên dịch thực hiện công việc khó khăn mà nhà phát triển sử dụng để làm, và ứng dụng của bạn giữ lại một cấu trúc lô-gic giống như mã đồng bộ. Kết quả là, bạn nhận được tất cả những lợi thế của lập trình không đồng bộ với một phần nhỏ của nỗ lực.

Hiểu cách các quy trình không đồng bộ hoạt động trong thế giới thực có thể giúp bạn hiểu cách sử dụng lập trình không đồng bộ trong các ứng dụng của bạn.

Kiểm tra một quá trình không đồng bộ trong thế giới thực

Làm bữa sáng là một ví dụ điển hình về một quá trình có lợi từ việc thực hiện các nhiệm vụ không đồng bộ. Bạn có thể nghĩ đến việc làm bữa sáng như một chuỗi các tác vụ có thể được thực hiện đồng bộ hoặc không đồng bộ.

  1. Nhận các nguyên liệu bữa sáng từ phòng đựng thức ăn.
  2. Rót một tách cà phê.
  3. Đun nóng một chảo, sau đó chiên ba lát thịt xông khói.
  4. Chiên hai quả trứng.
  5. Bánh mì nướng hai miếng.
  6. Truyền bơ và mứt trên bánh mì nướng.
  7. Đổ một ly nước cam.

Nếu bạn có kinh nghiệm nấu ăn, bạn có thể hoàn thành các hướng dẫn này một cách không đồng bộ. Bạn bắt đầu hâm nóng chảo cho thịt xông khói và trứng, sau đó lấy các thành phần từ phòng đựng thức ăn. Bạn cho bánh mì vào lò nướng, sau đó bắt đầu nấu thịt xông khói. Ở mỗi bước của quy trình, bạn bắt đầu một nhiệm vụ, rồi chuyển tiếp sang các tác vụ khác đã sẵn sàng cho sự chú ý của bạn.

Nấu ăn bữa sáng là một ví dụ tốt về công việc không đồng bộ không phải là song song. Một người (hoặc chuỗi hội thoại) có thể xử lý tất cả các tác vụ. Một người có thể làm cho bữa sáng không đồng bộ bằng cách bắt đầu tác vụ tiếp theo trước khi nhiệm vụ trước đó hoàn thành. Mỗi nhiệm vụ nấu ăn tiến triển bất kể ai đó đang tích cực xem quá trình. Ngay sau khi bạn bắt đầu làm nóng chảo, bạn có thể lấy nguyên liệu từ phòng đựng thức ăn. Sau khi thịt xông khói bắt đầu nấu, bạn có thể cho bánh mì vào lò nướng.

Đối với một thuật toán song song, bạn cần nhiều người nấu ăn (hoặc nhiều chủ đề). Một người nấu trứng, một khoai tây chiên thịt xông khói, v.v. Mỗi người tập trung vào một nhiệm vụ cụ thể của họ. Mỗi người đang nấu ăn (hoặc mỗi chuỗi hội thoại) đều bị chặn đồng thời chờ tác vụ hiện tại hoàn thành: Thịt xông khói sẵn sàng lật, bánh mì sẵn sàng bật lên trong máy nướng bánh mì, v.v.

Bằng cách sử dụng các kỹ thuật lập trình không đồng bộ, bạn có thể cải thiện hiệu quả và độ phản hồi của ứng dụng, giống như cách bạn có thể làm cho bữa sáng hiệu quả hơn bằng cách thực hiện nhiều tác vụ cùng một lúc.

Không đồng bộ cải thiện độ nhạy

Không đồng bộ là điều cần thiết cho các hoạt động có khả năng chặn, chẳng hạn như truy cập web. Đôi khi, việc truy nhập vào tài nguyên web bị chậm hoặc trì hoãn. Nếu một hoạt động như vậy bị chặn trong một quá trình đồng bộ, toàn bộ ứng dụng phải chờ. Trong một quy trình không đồng bộ, ứng dụng có thể tiếp tục với các công việc khác không phụ thuộc vào tài nguyên web cho đến khi tác vụ chặn có thể hoàn tất.

Bảng sau đây hiển thị các khu vực điển hình nơi lập trình không đồng bộ cải thiện độ phản hồi. Các API được liệt kê từ .NET và Windows Runtime chứa các phương pháp hỗ trợ lập trình không đồng bộ.

Vùng Ứng dụng Loại .NET có Phương pháp Không đồng bộ Loại Thời gian chạy Windows với Phương pháp Không đồng bộ
Truy nhập web HttpClient Windows.Web.Http.HttpClient, SyndicationClient
Làm việc với tệp JsonSerializer, StreamReader, StreamWriter, v.v. Tệp Lưu trữ
Làm việc với hình ảnh MediaCapture, BitmapEncoder, BitmapDecoder
Lập trình WCF Thao tác Đồng bộ và Không đồng bộ

Cách tạo và gọi các phương pháp không đồng bộ

Trong C#, các thao tác không đồng bộ được thực hiện bằng cách sử dụng các từ async khóa và await . Từ async khóa được sử dụng để xác định một phương pháp không đồng bộ, await trong khi từ khóa được sử dụng để gọi một phương pháp không đồng bộ và chờ đợi kết quả của nó mà không chặn luồng gọi. Các thao tác không đồng bộ thường TaskTask<T> được thực hiện bằng cách sử dụng hoặc các loại đại diện cho một hoạt động đang diễn ra có thể được chờ đợi.

Dưới đây là ví dụ về cách tạo và gọi tác vụ không đồng bộ trong C#:


using System;
using System.IO;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        string filePath = "example.txt";
        string content = await ReadFileAsync(filePath);
        Console.WriteLine(content);
    }

    public static async Task<string> ReadFileAsync(string filePath)
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            string content = await reader.ReadToEndAsync();
            return content;
        }
    }
}

Trong ví dụ này, phương ReadFileAsync pháp được xác định bằng cách sử dụng async từ khóa và có kiểu trả về là Task<string>. Từ async khóa cho Task<string> biết rằng phương pháp chứa các thao tác không đồng bộ và kiểu trả về cho biết phương thức trả về tác vụ đại diện cho thao tác không đồng bộ. Loại Task<string> là một tác vụ chung đại diện cho một thao tác không đồng bộ trả về một giá trị chuỗi. Phương ReadFileAsync pháp lấy một đường dẫn tệp như một tham số và đọc nội dung của tệp một cách không đồng bộ.

Phương Main pháp này cũng được định nghĩa là không đồng bộ, cho phép nó gọi phương pháp bằng ReadFileAsync cách sử dụng từ await khóa. Từ await khóa được sử dụng để cho biết rằng chương trình nên chờ kết quả của thao tác không đồng bộ trước khi tiếp tục. Trong trường hợp này, chương trình chờ cho các tập tin được đọc trước khi in nội dung của nó để giao diện điều khiển.

Tóm tắt

Trong đơn vị này, bạn đã học được về những lợi ích của lập trình không đồng bộ và làm thế nào nó có thể cải thiện độ nhạy của các ứng dụng của bạn. Bạn cũng đã học được cách tạo và gọi các phương pháp không đồng bộ bằng cách sử dụng các async từ khóa await và trong C#. Bằng cách sử dụng các kỹ thuật này, bạn có thể viết các ứng dụng hiệu quả hơn và đáp ứng có thể xử lý các hoạt động có khả năng chặn mà không cần đóng băng giao diện người dùng hoặc chặn các tác vụ khác.

Các điểm chính

  • Lập trình không đồng bộ giúp tăng cường hiệu suất ứng dụng và độ phản hồi.
  • C# cung cấp một phương pháp đơn giản hóa để lập trình không đồng bộ.
  • Lập trình không đồng bộ là mang lại lợi ích trong khả năng chặn các hoạt động như truy cập web.
  • Trong C#, các phương pháp không đồng bộ được tạo bằng cách sử dụng từ khóa async và được gọi bằng cách sử dụng từ await khóa.
  • Hoặc Task các loại Task<T> đại diện cho các thao tác đang diễn ra có thể được chờ đợi trong C#.