3

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

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

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

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应该真的是 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;
}

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

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

这有点尴尬,因为Session不是强类型。

于 2013-03-01T22:29:44.457 回答