0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Sử Dụng Task.WhenEach Trong .NET: Xử Lý Nhiệm Vụ Theo Thứ Tự Hoàn Thành

Đăng vào 3 ngày trước

• 3 phút đọc

Giới Thiệu

Khi làm việc với lập trình bất đồng bộ trong .NET, bạn thường phải xử lý nhiều tác vụ chạy song song. Truyền thống, chúng ta sử dụng:

  • Task.WhenAll – chờ tất cả các tác vụ hoàn thành.
  • Task.WhenAny – tiếp tục ngay khi một tác vụ hoàn thành.

Nhưng nếu bạn muốn xử lý từng tác vụ khi nó hoàn thành, mà không cần chờ tác vụ chậm nhất? Hãy tìm hiểu về Task.WhenEach (được giới thiệu trong .NET 6+).


Tại Sao Nên Sử Dụng Task.WhenEach?

Hãy tưởng tượng bạn gọi đến nhiều API với thời gian phản hồi khác nhau. Sử dụng Task.WhenAll, bạn phải chờ đợi API chậm nhất trước khi xử lý kết quả.

Task.WhenEach cho phép bạn:

  • Xử lý kết quả ngay lập tức khi mỗi tác vụ hoàn thành.
  • Cải thiện khả năng phản hồi trong các tình huống có kết quả một phần.
  • Giảm độ trễ trong các ứng dụng thời gian thực hoặc ứng dụng kiểu stream.

Ví Dụ

Sử Dụng Task.WhenAll

csharp Copy
var tasks = new[]
{
    Task.Delay(3000).ContinueWith(_ => "Task 1"),
    Task.Delay(1000).ContinueWith(_ => "Task 2"),
    Task.Delay(2000).ContinueWith(_ => "Task 3")
};

var results = await Task.WhenAll(tasks);
foreach (var result in results)
{
    Console.WriteLine($"Đã xử lý: {result}");
}

Thứ tự đầu ra:

Copy
Đã xử lý: Task 1
Đã xử lý: Task 2
Đã xử lý: Task 3

Dù Task 2 hoàn thành trước, kết quả vẫn được xử lý sau khi tất cả các tác vụ hoàn thành.


Sử Dụng Task.WhenEach

csharp Copy
await foreach (var task in Task.WhenEach(tasks))
{
    Console.WriteLine($"Đã xử lý: {await task}");
}

Thứ tự đầu ra:

Copy
Đã xử lý: Task 2
Đã xử lý: Task 3
Đã xử lý: Task 1

Bây giờ, mỗi kết quả được xử lý ngay khi tác vụ của nó hoàn thành, mang lại khả năng phản hồi nhanh hơn.


Trường Hợp Sử Dụng Thực Tế

  1. Tổng hợp API – Lấy dữ liệu từ nhiều API bên ngoài cùng một lúc.
  2. Xử lý tệp tin – Xử lý các tệp lớn lần lượt.
  3. Quét web – Trả về kết quả một phần cho người dùng theo cách tiến bộ.
  4. Tình huống streaming – Hành động trên dữ liệu từng phần thay vì chờ đợi tất cả.

Khi Nào Nên Sử Dụng Cái Gì

  • Task.WhenAll – khi bạn cần tất cả kết quả trước khi tiếp tục.
  • Task.WhenAny – khi bạn chỉ quan tâm đến tác vụ hoàn thành đầu tiên.
  • Task.WhenEach – khi bạn muốn xử lý tác vụ một cách tiến bộ.

Kết Luận

Task.WhenEach là một bước đột phá cho lập trình bất đồng bộ trong .NET. Nó giúp viết các ứng dụng phản hồi nhanh hơn và xử lý các tác vụ một cách hiệu quả mà không cần chờ đợi thao tác chậm nhất.

Nếu bạn chưa thử nghiệm, hãy bắt đầu thay thế một số tình huống WhenAll bằng WhenEach và cảm nhận sự khác biệt.


💡 Mẹo: Kết hợp Task.WhenEach với async streams (await foreach) để xây dựng các API phản hồi hoặc bảng điều khiển thời gian thực.


Các Thực Hành Tốt Nhất

  1. Kiểm tra lỗi: Luôn xử lý ngoại lệ trong mỗi tác vụ để tránh ứng dụng bị treo.
  2. Giới hạn số lượng tác vụ: Để tránh quá tải hệ thống, hãy giới hạn số lượng tác vụ chạy song song.
  3. Tối ưu hóa API: Sử dụng caching hoặc băm dữ liệu để cải thiện hiệu suất.

Cái Bẫy Thường Gặp

  1. Xử lý không đồng bộ sai cách: Đảm bảo rằng tất cả các tác vụ đều được xử lý đúng cách để tránh tình trạng rò rỉ tài nguyên.
  2. Không xử lý ngoại lệ: Nếu không cẩn thận, lỗi trong một tác vụ có thể làm hỏng toàn bộ quy trình.

Mẹo Hiệu Suất

  • Sử dụng ConfigureAwait(false) trong các tác vụ không liên quan đến UI để cải thiện hiệu suất.
  • Tối ưu hóa cách gọi API để giảm thiểu thời gian chờ.

Câu Hỏi Thường Gặp (FAQ)

Q: Task.WhenEach có tương thích với các phiên bản trước của .NET không?
A: Không, Task.WhenEach chỉ có sẵn trong .NET 6 và các phiên bản mới hơn.

Q: Có cách nào để xử lý kết quả theo thứ tự không?
A: Bạn có thể sử dụng một danh sách để lưu trữ kết quả và sắp xếp chúng sau khi tất cả tác vụ hoàn thành.

Tài Nguyên Tham Khảo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào