我最近开始在.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}}自称完成?)。
我也试过手动启动任务。在这种情况下,它只会崩溃,因为您无法手动启动任务。就我而言,它必须由系统来完成。
有任何线索吗?这个很难。
答案 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
没有强类型。