2013-01-02 33 views
27

Tôi đã viết một điều khiển ASP.NET tùy chỉnh và tôi vừa cập nhật nó để có trình xử lý sự kiện tải async. Bây giờ tôi nhận được lỗi này:Sự kiện vòng đời ASP.NET nào có thể không đồng bộ?

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>.

Trang không có thẻ <%@ Page Async="true" %> rồi. Vì vậy, tôi lấy nó rằng các điều khiển không thể có trình xử lý sự kiện tải không đồng bộ.

Tôi có thể tìm danh sách các sự kiện toàn diện trong vòng đời webform ASP.NET được cho phép là không đồng bộ ở đâu?

+2

Bài viết này có thể giúp bạn: http://msdn.microsoft.com/en-us/magazine/gg598924.aspx – Aristos

+1

Cảm ơn bạn. Chắc chắn là một đọc tốt, mặc dù nó không trả lời câu hỏi của tôi. –

+0

Điều này cũng giải thích một chút và cung cấp nhiều mã ví dụ hơn mã msdn, nhưng vẫn không trả lời câu hỏi của bạn:/ http://www.asp.net/web-forms/tutorials/aspnet-45/ using-asynchronous-methods-in-aspnet-45 – mirichan

Trả lời

28

Damian Edwards từ nhóm ASP.NET cho câu trả lời này:

Async void event handlers in web forms are only supported on certain events, as you've found, but are really only intended for simplistic tasks. We recommend using PageAsyncTask for any async work of any real complexity.

Levi Broderick từ nhóm ASP.NET cho câu trả lời này:

Async events in web applications are inherently strange beasts. Async void is meant for a fire and forget programming model. This works in Windows UI applications since the application sticks around until the OS kills it, so whenever the async callback runs there is guaranteed to be a UI thread that it can interact with. In web applications, this model falls apart since requests are by definition transient. If the async callback happens to run after the request has finished, there is no guarantee that the data structures the callback needs to interact with are still in a good state. Thus why fire and forget (and async void) is inherently a bad idea in web applications.

That said, we do crazy gymnastics to try to make very simple things like Page_Load work, but the code to support this is extremely complicated and not well-tested for anything beyond basic scenarios. So if you need reliability I’d stick with RegisterAsyncTask.

Vì vậy, tôi nghĩ câu trả lời cho câu hỏi của tôi là: "Đó là câu hỏi sai."

Câu hỏi đúng sẽ là "Làm cách nào tôi không đồng bộ trong ứng dụng Biểu mẫu web ASP.NET của tôi?" Và câu trả lời là để chèn đoạn này bên aspx tập tin code-behind của bạn:

this.RegisterAsyncTask(new PageAsyncTask(async cancellationToken => { 
    var result = await SomeOperationAsync(cancellationToken); 
    // do something with result. 
})); 

lừa này cùng làm việc bên trong điều khiển tùy chỉnh ASP.NET, chỉ cần sử dụng this.Page.RegisterAsyncTask để thay thế.

1

Trang này giải thích cách vòng đời xử lý sự kiện trong trang không đồng bộ khác với những trang đồng bộ trong ASP.NET 2.0 (Hình 2 là đặc biệt hữu ích):

Wicked Code: Asynchronous Pages in ASP.NET 2.0

Bạn cũng có thể tìm thấy câu hỏi này SO sử dụng (nó nói về các thông báo lỗi tương tự):

async keyword and choice of the TaskScheduler

+0

Cảm ơn, @Lokerim. Đặc biệt, bit hữu ích là 'Page.RegisterAsyncTask', cho phép ASP.NET điều khiển tùy chỉnh của tôi thực hiện bất kỳ hoạt động async nào, mặc dù ASP.NET không cho phép tôi sử dụng" async void Page_Load "trong điều khiển tùy chỉnh của mình . Cảm ơn! –

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