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

时间:2013-03-01 21:33:54

标签: c# asp.net asynchronous

我最近开始在.NET 4.0上使用.NET 4.5,我很喜欢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;
}

我收到的错误如下。

  

异步模块或处理程序在异步时完成   手术还在等待。

我也尝试了以下代码而没有运气。

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

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

在那种情况下,它的状态将持续WaitingForActivation,这可能表明它没有被放入系统要执行的任务队列中(可能是因为系统正在等待{ {1}}自称完成?)。

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

有任何线索吗?这个很难。

1 个答案:

答案 0 :(得分: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没有强类型。