28

カスタムASP.NETコントロールを作成し、非同期のLoadイベントハンドラーを持つように更新しました。今、私はこのエラーを受け取っています:

現在、非同期操作を開始することはできません。非同期操作は、非同期ハンドラーまたはモジュール内で、またはページライフサイクルの特定のイベント中にのみ開始できます。ページの実行中にこの例外が発生した場合は、ページが<%@ Page Async = "true"%>とマークされていることを確認してください。

ページには<%@ Page Async="true" %>すでにタグが付いています。したがって、コントロールは非同期ロードイベントハンドラーを持つことができないと思います。

非同期が許可されているASP.NETWebフォームライフサイクルのイベントの包括的なリストはどこにありますか?

4

2 に答える 2

28

ASP.NETチームのDamianEdwardsは、次のように回答しました。

Webフォームの非同期voidイベントハンドラーは、ご存知のとおり、特定のイベントでのみサポートされていますが、実際には単純なタスクのみを対象としています。実際に複雑な非同期作業には、PageAsyncTaskを使用することをお勧めします。

ASP.NETチームのLeviBroderickは、次のように回答しました。

Webアプリケーションの非同期イベントは、本質的に奇妙な獣です。Async voidは、ファイアアンドフォーゲットプログラミングモデルを対象としています。これは、OSがアプリケーションを強制終了するまでアプリケーションが存続するため、Windows UIアプリケーションで機能します。したがって、非同期コールバックが実行されるたびに、対話できるUIスレッドが存在することが保証されます。Webアプリケーションでは、要求は定義上一時的なものであるため、このモデルは崩壊します。リクエストの終了後に非同期コールバックが実行された場合、コールバックが対話する必要のあるデータ構造がまだ良好な状態であるという保証はありません。したがって、なぜファイアアンドフォーゲット(および非同期ボイド)がWebアプリケーションでは本質的に悪い考えであるのか。

とは言うものの、私たちはPage_Loadのような非常に単純なものを機能させるためにクレイジーな体操を行っていますが、これをサポートするコードは非常に複雑であり、基本的なシナリオ以外のことについては十分にテストされていません。したがって、信頼性が必要な場合は、RegisterAsyncTaskを使用します。

ですから、私の質問に対する答えは、「それは間違った質問だ」ということだと思います。

正しい質問は、「ASP.NET Webフォームアプリケーションでどのように非同期にする必要がありますか?」です。そして答えは、このスニペットをaspx分離コードファイル内に挿入することです。

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

これと同じトリックがASP.NETカスタムコントロール内で機能しますthis.Page.RegisterAsyncTask。代わりに使用してください。

于 2013-02-09T23:39:31.470 に答える
1

このページでは、非同期ページでのライフサイクルイベント処理がASP.NET 2.0の同期ページでの処理とどのように異なるかを説明します(図2は特に役立ちます)。

邪悪なコード:ASP.NET2.0の非同期ページ

このSOの使用に関する質問もあります(同じエラーメッセージについて説明しています)。

非同期キーワードとTaskSchedulerの選択

于 2013-02-01T04:36:47.420 に答える