3

最近、.NET4.0よりも.NET4.5を使い始めましたが、この機能が大好きasyncです。

ただし、ASP .NETのGlobal.asaxのSession_Startイベントで使用すると、何をしても(待機を実行してセッションにアクセスした場合)、エラーが発生します。

これがコードです。問題を再現できると確信しています。問題は-どうすればそれを解決できますか?

protected async void Session_Start(object sender, EventArgs e)
{
    var stuff = await UserAccess.RetrieveSomeStuff();
    Session["Stuff"] = stuff;
}

私が受け取っているエラーは次のとおりです。

非同期操作がまだ保留中に、非同期モジュールまたはハンドラーが完了しました。

私も運が悪かった次のコードを試しました。

protected void Session_Start(object sender, EventArgs e)
{
    var stuffTask = UserAccess.RetrieveSomeStuff();
    stuffTask.Wait();

    Session["Stuff"] = stuffTask.Result;
}

そのシナリオでは、ステータスがWaitingForActivation常にの状態になります。これは、システムによって実行されるタスクのキューに入れられていないことを示している可能性があります(おそらく、システムがWait()呼び出し自体の終了を待機しているためですか?)。

また、手動でタスクを開始してみました。その場合、手動でタスクを開始できないため、クラッシュするだけです。私に関する限り、それはシステムによって行われなければなりません。

どんな手掛かり?これはタフです。

4

1 に答える 1

5

あなたが得ているのは、そのイベントのハンドラーをInvalidOperationException持つことができないことを伝える ASP.NET の方法です。async

しかし、実際にやりたいことは、非同期リソースの初期化を開始し、後で実際に必要になったときに (非同期で) 待機することです。したがって、あなたのオブジェクトは、次のようにSession実際には である必要があります。Task<T>

protected void Session_Start(object sender, EventArgs e)
{
    Session["Stuff"] = LoadMyDataAsync();
}

static async Task<int> LoadMyDataAsync()
{
    await Task.Delay(1000);
    return 13;
}

次に、次のように使用できます (この例は ASP.NET MVC 4 コントローラーですが、WebAPI および非同期 WebPages は同様の手法を使用できます)。

public async Task<ActionResult> Index()
{
    ViewBag.Message = await (Session["Stuff"] as Task<int>);
    return View();
}

Session強く型付けされていないため、少し厄介です。

于 2013-03-01T22:29:44.457 に答える