2014-05-01 15 views
7

Tôi đang cố gắng để hiểu được lý do tại sao là nó xấu để làm: (thông báo, bối cảnh ở đây là asp.net, bất kể lý do đơn giản rằng async void không thể được theo dõi)xử lý sự kiện không đồng bộ void - làm rõ?

public async void Page_Load(object sender, EventArgs e) 
{ 
... 
} 

Vâng, sau khi điều tra một chút, tôi thấy vài khác nhau lý do:

  • Damian Edwards nói here rằng:

    01.235.

    Async xử lý khoảng trống kiện trong các hình thức web chỉ được hỗ trợ trên một số sự kiện , như bạn đã thấy, nhưng thực sự chỉ dành cho đơn giản nhiệm vụ. Chúng tôi khuyên bạn nên sử dụng PageAsyncTask cho bất kỳ công việc không đồng bộ nào của bất kỳ sự phức tạp thực sự nào của .

  • Levi Says here rằng:

    Async sự kiện trong các ứng dụng web vốn đã thú lạ. Async void có nghĩa là cho một đám cháy và quên mô hình lập trình. Thao tác này hoạt động trong các ứng dụng Windows UI từ khi ứng dụng di chuyển xung quanh cho đến khi hệ thống giết chết nó, vì vậy bất cứ khi nào cuộc gọi lại không đồng bộ chạy ở đó được đảm bảo làm chủ đề giao diện người dùng. Trong các ứng dụng web, mô hình này bị tách rời do các yêu cầu theo định nghĩa thoáng qua. Nếu gọi lại không đồng bộ xảy ra để chạy sau khi yêu cầu hoàn tất, có không đảm bảo rằng cấu trúc dữ liệu mà cuộc gọi lại cần tương tác vẫn đang ở trạng thái tốt. Vì vậy, tại sao lửa và quên (và async void) vốn đã là một ý tưởng tồi trong các ứng dụng web.

    Điều đó nói rằng, chúng tôi tập thể dục điên để cố gắng làm những việc rất đơn giản như công việc Page_Load, nhưng mã để hỗ trợ điều này cực kỳ phức tạp và không được thử nghiệm cho bất kỳ điều gì ngoài kịch bản cơ bản. Vì vậy, nếu bạn cần độ tin cậy, tôi sẽ gắn bó với RegisterAsyncTask.

  • This site nói:

    Như chúng ta đã biết vòng đời trang của chúng tôi có một tập hợp các sự kiện mà bị sa thải trong một trật tự được xác định trước và sự kiện tiếp theo sẽ bị sa thải chỉ khi sự kiện cuối cùng hoàn thành. Vì vậy, nếu chúng tôi sử dụng cách thức không đồng bộ Page_Load ở trên, sự kiện này sẽ được kích hoạt trong sự kiện vòng đời trang khi nó đạt đến async, chuỗi hiện tại được miễn phí và một chủ đề khác được gán để hoàn thành tác vụ không đồng bộ, nhưng ASP.NET không thể thực thi sự kiện tiếp theo trong vòng đời vì Page_Load chưa hoàn thành. Và bối cảnh đồng bộ hóa cơ bản chờ cho đến khi hoạt động không đồng bộ hoàn tất.Sau đó, sự kiện tiếp theo của vòng đời trang sẽ là phát sinh toàn bộ quá trình ở chế độ đồng bộ.

  • This trang web nói

    khi kiểu trả về là void, các người gọi có thể giả định phương pháp này hoàn tất vào thời điểm nó sẽ trả về. Sự cố này có thể xuất hiện theo nhiều cách không mong muốn. Nó thường sai để cung cấp một thực hiện async (hoặc ghi đè) của một phương pháp khoảng trống-trở trên một giao diện (hoặc lớp cơ sở). Một số sự kiện cũng giả định rằng trình xử lý của chúng hoàn tất khi chúng trả về.

Tôi thấy ở đây rất khác nhau (không chồng chéo) lý do.

Câu hỏi:

là vinh quang/lý do thực sự mà chúng ta không nên viết public async void Page_Load(object sender, EventArgs e)?


nb, tôi cũng không biết tại sao nó là một vấn đề vì 4.5 không sử dụng UseTaskFriendlySynchronizationContext mà nó aim is to support:

protected async void Page_Load(object sender, EventArgs e){...}

+0

Thông báo như thế nào tất cả các liên kết liên quan ASP nói rằng đó là okay, và tất cả các liên kết liên quan phi ASP nói rằng bạn phải rất cẩn thận về cách bạn sử dụng 'async void'. Điều đó sẽ cho bạn biết điều gì đó, rằng ASP là đặc biệt. Và nếu bạn đọc qua một số liên kết của riêng bạn, họ thậm chí còn giải thích * tại sao * ASP là đặc biệt và cách nó cho phép các phương thức 'async void' hoạt động như bạn muốn; tất nhiên, đó là chỉ cho các trường hợp đơn giản; nó cũng giải thích khi nó không hoạt động, và phải làm gì sau đó. – Servy

+0

Trang máy chủ hoạt động. – Servy

+0

@Servy Levi và Damian đang trong quá trình phát triển asp.net .... vì vậy tôi thấy khó mà không tin họ .... nhưng mặt khác ....các lý do khác có vẻ hợp pháp .... vì vậy ... :-) –

Trả lời

5

Các bài viết bạn liên kết để làm cho những lý do khá rõ ràng. Không sử dụng nó bởi vì nó không đáng tin cậy ngoài những kịch bản cơ bản nhất. Chỉ có quá nhiều thủ thuật theo dõi không đồng bộ, chúng ta có thể kéo trong bối cảnh đồng bộ hóa trên các phương thức void không đồng bộ. Chúng tôi đã làm việc để làm cho những kịch bản cơ bản đó hoạt động, nhưng hướng dẫn chung của chúng tôi là tránh sử dụng chúng và thay vào đó đăng ký một cách rõ ràng công việc không đồng bộ.

+0

Xin chào Damian, trong nỗ lực "tránh async void" Tôi đã sử dụng 'RegisterAsyncTask' trong trình xử lý sự kiện Page_Load, nhưng tôi không thể nhận được bất kỳ dữ liệu nào liên kết với Telerik RadGrid. Tất cả các phương thức đều được gọi và trả về dữ liệu, nhưng kết buộc dữ liệu bị lỗi. Bạn có thể giúp tôi hiểu điều gì có thể xảy ra không? – pkamathk

2

tôi vẫn chưa xác minh này, nhưng tôi nghĩ rằng đó là OK để sử dụng async void Page_Load(...) trong ASP.NET 4.5 WebForms, miễn là trang có tuyên bố <%@ Page Async="true" ... %>.

Tôi nghĩ như vậy dựa trên số implementation of AspNetSynchronizationContext.OperationStarted, được gọi khi phương thức async void được gọi trên một chuỗi với AspNetSynchronizationContext. Dưới đây là một lời nhận xét có liên quan:

// If the caller tries to kick off an asynchronous operation while we are not 
// processing an async module, handler, or Page, we should prohibit the operation. 

Rõ ràng, các trang có Async="true" không vi phạm yêu cầu này, và quá trình xử lý yêu cầu HTTP sẽ không được hoàn thành cho đến khi tất cả các hoạt động cấp phát đã hoàn thành, bao gồm async void người.

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