具有异步Session_Start方法时的会话问题?

Mat*_*zen 3 c# asp.net asynchronous

我最近开始使用.NET 4.5而不是.NET 4.0,我很喜欢这个async功能.

但是,在我的Global.asax中的Session_Start事件中在ASP .NET中使用它时,无论我做什么(如果我执行await并访问会话),它都会导致错误.

这是代码.我相信你可以复制这个问题.问题是 - 我该如何解决?

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

我收到的错误如下.

在异步操作仍处于挂起状态时完成异步模块或处理程序.

我也试过以下代码没有运气.

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

    Session["Stuff"] = stuffTask.Result;
}
Run Code Online (Sandbox Code Playgroud)

在那种情况下,它将具有WaitingForActivation持续的状态,这可能表明它没有被放入系统要执行的任务队列中(可能是因为系统正在等待Wait()呼叫本身完成?).

我也试过手动启动任务.在这种情况下,它只会崩溃,因为您无法手动启动任务.就我而言,它必须由系统来完成.

任何线索?这个很难.

Ste*_*ary 5

InvalidOperationException你得到的是告诉你,你不能有一个ASP.NET的的方式async针对该事件处理程序.

但实际上,您要做的是启动一些异步资源初始化,然后(异步)在您实际需要时稍后等待它.所以你的对象Session应该是a Task<T>,像这样:

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

static async Task<int> LoadMyDataAsync()
{
    await Task.Delay(1000);
    return 13;
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以像这样使用它(这个例子是一个ASP.NET MVC 4控制器,但是WebAPI和异步WebPages可以使用类似的技术):

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

这有点尴尬,因为Session没有强类型.