gpt4 book ai didi

asp.net-mvc - 从 Session_Start 调用异步方法

转载 作者:行者123 更新时间:2023-12-02 21:22:08 25 4
gpt4 key购买 nike

如何从 Global.asax 中的 Session_Start 调用 async 方法?

全局.asax:

    protected async Task Session_Start(object sender, EventArgs e)
{
Session.Timeout = 10;

// Do some asynch work
await repository.SetStatsInfo(System.DateTime.Now);
}

异步方法:

    public async Task SetStatsInfo(DateTime time)
{
using (ApplicationDBContext db = new ApplicationDBContext())
{
// Do stuff (update visitors counter in db) ..

await db.SaveChangesAsync();

}
}

我可以同步运行它(定义void Session_Start等),这是有效的,但更喜欢异步方式,这样访问数据库就不会阻塞。

像这样使用'async Task' for Session_Start运行,代码不会被执行,未命中 session_start 内的断点。

最佳答案

据我了解,ASP 有一个指定线程,它是唯一有权访问 HttpContext.Current 对象并进而访问 Session 的线程(HttpContext.Current.Session) 非常类似于 Windows 应用程序中的 UI 线程。因此,在 Session_Start 回调中执行 .Wait().Result 将会给您带来未知的结果和/或导致进程死锁。

似乎有很多方法来管理任务的执行线程,主要的方法是通过 TaskScheduler 类 https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx#Sync 指定您的任务在特定的同步上下文中运行。

但是,由于 Task 类被设计为实现来自 APM(异步编程模型)模式的 IAsyncResult,这使得 Task 向后兼容较旧的 APM 模式代码(根据我的理解) ASP 最初是建立在)。不过,这需要一些集成工作https://blogs.msdn.microsoft.com/mazhou/2011/10/04/the-asynchronous-programming-models/ (标准 APM)。

.Net 4.5 引入了一个很好的任务包装器 (EventHandlerTaskAsyncHelper),利用 APM 风格的 HttpApplication 来执行异步操作以支持。它满足访问Session对象的所有要求,并在HttpApplication中正确执行:

public override void Init()
{
base.Init();
//EventHandlerTaskAsyncHelper Wraps the task call in an APM-style BeginEventHandler, EndEventHandler
var wrapper = new EventHandlerTaskAsyncHelper(AsyncSessionStart);
this.AddOnAcquireRequestStateAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler);
}

private async Task AsyncSessionStart(Object sender, EventArgs evtArgs)
{
//The only caveat is we have to check IsNewSession to see if it was created in this call
//This doesn't need to be applied for other AddOn*Async wire-ups
if (!Session.IsNewSession)
return;

await doSomethingAsync();
}

//I recall seeing something that for session state to be active, this callback has to be declared, even if empty
protected void Session_Start(object sender, EventArgs e)
{
//Synchronous session
}

关于asp.net-mvc - 从 Session_Start 调用异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38956394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com