2012-04-04 37 views
15

Tôi đã làm việc trên một bài thuyết trình và nghĩ rằng những điều sau đây sẽ thất bại vì ActionResult không được trả về đúng ngữ cảnh. Tôi đã tải thử nghiệm nó với VS và không có lỗi. Tôi đã gỡ lỗi nó và biết rằng nó đang chuyển đổi chủ đề. Vì vậy, nó có vẻ như nó là mã legit.Gọi ConfigureAwait từ một ASP.NET MVC Action

ASP.NET không quan tâm đến ngữ cảnh hoặc chủ đề nào giống như ứng dụng khách? Nếu vậy, mục đích của AspNetSynchronizationContext là gì? Tôi không cảm thấy đúng khi đặt một ConfigureAwait trong chính hành động đó. Có điều gì đó không ổn về nó. Bất cứ ai có thể giải thích?

public async Task<ActionResult> AsyncWithBackendTest() 
    { 
     var result = await BackendCall().ConfigureAwait(false); 
     var server = HttpContext.Server; 
     HttpContext.Cache["hello"] = "world"; 
     return Content(result); 
    } 
+2

Câu trả lời đúng sẽ cho biết lý do tại sao thực hiện việc này hoàn toàn OK hoặc nên đưa ra ví dụ về những gì không thành công khi bạn thực hiện việc này.Ruột của tôi nói với tôi rằng tôi không nên, nhưng tôi muốn có sự thật để ủng hộ tôi. –

Trả lời

6

ASP.NET không có 'chuỗi giao diện người dùng' cần nhiều ứng dụng khách hàng thực hiện (do khung giao diện người dùng bên dưới nó). bối cảnh đó không phải là về chủ đề mối quan hệ, nhưng để theo dõi sự tiến bộ trang (và những thứ khác, như triển khai xung quanh bối cảnh an ninh cho các yêu cầu)

Stephen Toub mentions this in an MSDN article:

Windows Forms không phải là môi trường chỉ cung cấp lớp học bắt nguồn từ lớp SynchronizationContext. ASP.NET cũng cung cấp một, AspNetSynchronizationContext, mặc dù nó không công khai và không có nghĩa là để tiêu thụ bên ngoài. Thay vào đó, nó được sử dụng dưới các trang bìa của ASP.NET để tạo điều kiện cho các chức năng trang không đồng bộ trong ASP.NET 2.0 (để biết thêm thông tin, hãy xem msdn.microsoft.com/msdnmag/issues/05/10/WickedCode). Việc triển khai cho phép ASP.NET ngăn hoàn thành xử lý trang cho đến khi tất cả các yêu cầu không đồng bộ xuất sắc đã được hoàn thành.

Chi tiết hơn một chút về ngữ cảnh đồng bộ được đưa ra trong Stephen Cleary's article from last year.

Hình 4 đặc biệt cho thấy rằng nó không có hành vi 'thread cụ thể' của WinForms/WPF, nhưng toàn bộ điều là một đọc tuyệt vời.

Nếu có nhiều hoạt động hoàn chỉnh cùng một lúc cho cùng một ứng dụng, AspNetSynchronizationContext sẽ đảm bảo rằng họ thực hiện cùng một lúc . Chúng có thể thực thi trên bất kỳ chuỗi nào, nhưng chuỗi đó sẽ có bản sắc và văn hóa của trang gốc.

+0

Trong async dựa trên sự kiện, xử lý các yêu cầu không đồng bộ xuất sắc được áp dụng, nhưng dường như không áp dụng trong async dựa trên nhiệm vụ, vì sẽ không có bất kỳ lời gọi xuất sắc nào vào cuối Hành động. Ngoài ra, thông qua gỡ lỗi, tôi thấy rằng nhận dạng biểu mẫu của người dùng và ngôn ngữ của họ (bảo mật & văn hóa) vẫn còn nguyên vẹn sau khi ConfigureAwait. Vì vậy, tôi đang đọc lý do cho SyncContext, nhưng không có gì có vẻ bị hỏng. Tôi có thể làm gì để chứng minh rằng ConfigureAwait không nên được sử dụng ở đây? –

4

Trong mã của bạn, HttpContext là thành viên của lớp cơ sở AsyncController của bạn. Nó không phải là ngữ cảnh hiện tại cho chuỗi thực hiện.

Ngoài ra, trong trường hợp của bạn, HttpContext vẫn hợp lệ vì yêu cầu chưa hoàn tất.

Tôi không thể kiểm tra điều này vào lúc này, nhưng tôi hy vọng nó sẽ thất bại nếu bạn sử dụng System.Web.HttpContext.Current thay vì HttpContext.

P.S. Bảo mật là luôn luôn được truyền, bất kể ConfigureAwait - điều này có ý nghĩa nếu bạn nghĩ về điều đó. Tôi không chắc chắn về văn hóa, nhưng tôi sẽ không ngạc nhiên nếu nó luôn được truyền bá.

+0

Đúng, các biến của tôi sẽ luôn hợp lệ vì chúng chỉ được đưa vào trong ngăn xếp. Nhưng ngay cả System.Web.HttpContext.Current vẫn có dữ liệu hợp lệ và chính xác. –

+0

'BackendCall' có trả về đồng bộ không? –

+0

Không. Bên cạnh một kiểm tra hợp lý, tôi đã gỡ lỗi nó và xem nó chuyển chủ đề. –

Các vấn đề liên quan