Đây là một câu hỏi rất hay và hiểu được đó là chìa khóa để hiểu tại sao IO không đồng bộ lại quan trọng như vậy. Lý do tại sao tính năng async/await mới đã được thêm vào C# 5.0 là đơn giản hóa việc viết mã không đồng bộ. Hỗ trợ xử lý không đồng bộ trên máy chủ không phải là mới tuy nhiên, nó tồn tại kể từ ASP.NET 2.0.
Giống như Steve cho bạn thấy, với xử lý đồng bộ, mỗi yêu cầu trong ASP.NET (và WCF) lấy một chủ đề từ nhóm chủ đề. Vấn đề anh ta giới thiệu là một vấn đề nổi tiếng được gọi là "starvation thread thread". Nếu bạn tạo IO đồng bộ trên máy chủ của mình, luồng thread thread sẽ vẫn bị chặn (không làm gì) trong suốt thời gian của IO.Vì có một giới hạn về số lượng các chủ đề trong nhóm luồng, dưới tải, điều này có thể dẫn đến tình huống mà tất cả các luồng chủ đề đang bị chặn chờ IO và các yêu cầu bắt đầu được xếp hàng đợi, làm tăng thời gian phản hồi. Vì tất cả các chủ đề đang chờ một IO hoàn thành, bạn sẽ thấy một CPU chiếm gần 0% (mặc dù thời gian đáp ứng đi qua mái nhà).
Những gì bạn đang yêu cầu (Tại sao chúng ta không thể sử dụng một threadpool lớn hơn?) là một câu hỏi rất hay. Như một vấn đề của thực tế, đây là cách hầu hết mọi người đã được giải quyết vấn đề đói hồ bơi thread cho đến bây giờ: chỉ có nhiều chủ đề trên hồ bơi thread. Một số tài liệu từ Microsoft thậm chí chỉ ra rằng như là một sửa chữa cho các tình huống khi hồ bơi thread đói có thể xảy ra. Đây là một giải pháp có thể chấp nhận được, và cho đến khi C# 5.0, nó dễ dàng hơn nhiều để làm điều đó, hơn viết lại mã của bạn hoàn toàn không đồng bộ.
Có một vài vấn đề với phương pháp này mặc dù:
Không có giá trị mà làm việc trong mọi tình huống: số lượng đề hồ bơi thread bạn sẽ cần phụ thuộc tuyến tính vào thời gian IO và tải trên máy chủ của bạn. Thật không may, độ trễ IO hầu như không thể đoán trước. Đây là một ví dụ: Giả sử bạn thực hiện yêu cầu HTTP cho dịch vụ web của bên thứ ba trong ứng dụng ASP.NET của bạn, mất khoảng 2 giây để hoàn tất. Bạn gặp phải nạn đói trong hồ bơi chủ đề, vì vậy bạn quyết định tăng kích thước nhóm luồng lên, giả sử, 200 chủ đề, và sau đó nó bắt đầu hoạt động tốt trở lại. Vấn đề là có thể vào tuần tới, dịch vụ web sẽ có vấn đề kỹ thuật làm tăng thời gian phản ứng của họ lên 10 giây. Tất cả sự đột ngột của hồ bơi, chủ đề đói là trở lại, bởi vì chủ đề bị chặn lâu hơn 5 lần, vì vậy bây giờ bạn cần phải tăng số lượng 5 lần, lên 1000 chủ đề.
Khả năng mở rộng và hiệu suất: Vấn đề thứ hai là nếu bạn làm như vậy, bạn sẽ vẫn sử dụng một chuỗi cho mỗi yêu cầu. Chủ đề là một nguồn tài nguyên đắt tiền. Mỗi luồng được quản lý trong .NET yêu cầu cấp phát bộ nhớ 1 MB cho ngăn xếp. Đối với một trang web tạo IO trong 5 giây, và với tải 500 yêu cầu mỗi giây, bạn sẽ cần 2,500 luồng trong nhóm chủ đề của mình, điều đó có nghĩa là 2,5 GB bộ nhớ cho các chuỗi các chuỗi sẽ không làm gì cả. Sau đó, bạn có vấn đề về chuyển đổi ngữ cảnh, điều này sẽ làm mất hiệu suất hoạt động của máy của bạn (ảnh hưởng đến tất cả các dịch vụ trên máy tính, không chỉ ứng dụng web của bạn). Mặc dù Windows thực hiện khá tốt công việc bỏ qua các chủ đề chờ đợi, nhưng nó không được thiết kế để xử lý một số lượng lớn các luồng. Hãy nhớ rằng hiệu quả cao nhất thu được khi số lượng các luồng chạy bằng với số lượng các CPU logic trên máy (thường không quá 16).
Vì vậy, tăng kích thước của nhóm luồng là giải pháp và mọi người đã làm điều đó trong một thập kỷ (ngay cả trong các sản phẩm của Microsoft), nó chỉ ít khả năng mở rộng và hiệu quả hơn về bộ nhớ và CPU sử dụng, và bạn luôn luôn ở lòng thương xót của một sự gia tăng đột ngột của IO độ trễ mà có thể gây ra đói. Cho đến C# 5.0, độ phức tạp của mã không đồng bộ không đáng để gây rắc rối cho nhiều người. async/await thay đổi mọi thứ như bây giờ, bạn có thể hưởng lợi từ khả năng mở rộng của IO không đồng bộ, và viết mã đơn giản, cùng một lúc.
Chi tiết khác: http://msdn.microsoft.com/en-us/library/ff647787.aspx "Sử dụng cuộc gọi không đồng bộ để gọi dịch vụ web hoặc đối tượng ở xa khi có cơ hội thực hiện xử lý song song bổ sung trong khi cuộc gọi dịch vụ Web tiến hành. Các cuộc gọi dịch vụ Web đi được thực hiện bằng cách sử dụng các chủ đề từ nhóm chủ đề ASP.NET Chặn các cuộc gọi để giảm số lượng các chuỗi có sẵn để xử lý các yêu cầu gửi đến khác. "
Trả lời này không trả lời phần thứ hai của câu hỏi. – nunespascal
Tốt hợp lý về lý do tại sao chuyển sang mẫu không đồng bộ. – eduncan911
Tôi không nghĩ rằng điều này giải quyết một thực tế rằng bất kể I/O là không thể đoán trước và bất cứ điều gì khác được quy định, người dùng vẫn phải chờ đợi cho tất cả mọi thứ để có được thực hiện trước khi nhận được một phản ứng. Thực tế là bản thân máy chủ web/http có thể xử lý tải nhiều hơn không có nghĩa là nó có thể xử lý hoàn toàn yêu cầu. Tôi không thấy làm thế nào async giải quyết điều này khác hơn là thay đổi cách thức mọi thứ được phân phối và có khả năng giới thiệu chuyển đổi bối cảnh đắt tiền hơn. – nilskp