Bạn có thể thấy bài viết MSDN của tôi về chủ đề này hữu ích ; Tôi đã dành rất nhiều không gian trong bài viết đó mô tả khi nào bạn nên sử dụng async
trên ASP.NET, không chỉ là cách sử dụng async
trên ASP.NET.
Tôi có một số lo ngại khi sử dụng các hành động không đồng bộ trong ASP.NET MVC. Khi nó cải thiện hiệu suất của các ứng dụng của tôi và khi nào - không.
Đầu tiên, hiểu rằng async
/ await
là tất cả về giải phóng chủ đề . Trên các ứng dụng GUI, chủ yếu là giải phóng luồng GUI để trải nghiệm người dùng tốt hơn. Trên các ứng dụng máy chủ (bao gồm ASP.NET MVC), chủ yếu là giải phóng chuỗi yêu cầu để máy chủ có thể mở rộng quy mô.
Đặc biệt, nó sẽ không:
- Làm cho yêu cầu cá nhân của bạn hoàn thành nhanh hơn. Trong thực tế, họ sẽ hoàn thành (chỉ một chút thiếu niên) chậm hơn.
- Quay trở lại trình gọi / trình duyệt khi bạn nhấn một
await
. await
chỉ "nhường" cho nhóm luồng ASP.NET, không cho trình duyệt.
Câu hỏi đầu tiên là - có tốt không khi sử dụng hành động async ở mọi nơi trong ASP.NET MVC?
Tôi muốn nói rằng thật tốt khi sử dụng nó ở mọi nơi bạn đang thực hiện I / O. Nó có thể không nhất thiết có lợi , mặc dù (xem bên dưới).
Tuy nhiên, thật tệ khi sử dụng nó cho các phương thức gắn với CPU. Đôi khi các nhà phát triển nghĩ rằng họ có thể nhận được lợi ích async
bằng cách chỉ cần gọi Task.Run
trong bộ điều khiển của họ, và đây là một ý tưởng khủng khiếp. Bởi vì mã đó kết thúc việc giải phóng chuỗi yêu cầu bằng cách chiếm một luồng khác, do đó không có lợi ích gì cả (và trên thực tế, họ đang phải chịu hình phạt của các chuyển đổi luồng bổ sung)!
Tôi có nên sử dụng async / await từ khóa khi tôi muốn truy vấn cơ sở dữ liệu (thông qua EF / NHibernate / ORM khác) không?
Bạn có thể sử dụng bất cứ phương pháp nào đang chờ bạn có sẵn. Ngay bây giờ hầu hết các cầu thủ lớn đều hỗ trợ async
, nhưng có một số ít thì không. Nếu ORM của bạn không hỗ trợ async
, thì đừng cố gắng bọc nó Task.Run
hoặc bất cứ thứ gì tương tự (xem bên trên).
Lưu ý rằng tôi đã nói "bạn có thể sử dụng". Nếu bạn đang nói về ASP.NET MVC với một phụ trợ cơ sở dữ liệu, thì bạn (gần như chắc chắn) sẽ không nhận được bất kỳ lợi ích về khả năng mở rộng nào async
. Điều này là do IIS có thể xử lý các yêu cầu đồng thời hơn nhiều so với một phiên bản duy nhất của máy chủ SQL (hoặc RDBMS cổ điển khác). Tuy nhiên, nếu phụ trợ của bạn hiện đại hơn - cụm máy chủ SQL, Azure SQL, NoQuery, v.v. - và phụ trợ của bạn có thể mở rộng và nút cổ chai khả năng mở rộng của bạn là IIS, thì bạn có thể nhận được lợi ích về khả năng mở rộng async
.
Câu hỏi thứ ba - Bao nhiêu lần tôi có thể sử dụng các từ khóa đang chờ để truy vấn cơ sở dữ liệu không đồng bộ trong MỘT phương thức hành động?
Như nhiều như bạn muốn. Tuy nhiên, lưu ý rằng nhiều ORM có quy tắc một thao tác cho mỗi kết nối. Cụ thể, EF chỉ cho phép một hoạt động trên mỗi DbContext; điều này đúng cho dù hoạt động là đồng bộ hay không đồng bộ.
Ngoài ra, hãy ghi nhớ khả năng mở rộng của phụ trợ của bạn một lần nữa. Nếu bạn gặp một phiên bản duy nhất của SQL Server và IIS của bạn đã có khả năng giữ cho SQLServer hoạt động hết công suất, thì việc nhân đôi hoặc tăng gấp ba áp lực lên SQLServer sẽ không giúp ích gì cho bạn cả.