Dan*_*lle 4 asp.net-mvc session asynchronous async-await .net-4.5
如何在Global.asax中调用异步方法Session_Start?
Global.asax中:
protected async Task Session_Start(object sender, EventArgs e)
{
Session.Timeout = 10;
// Do some asynch work
await repository.SetStatsInfo(System.DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)
异步方法:
public async Task SetStatsInfo(DateTime time)
{
using (ApplicationDBContext db = new ApplicationDBContext())
{
// Do stuff (update visitors counter in db) ..
await db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
我可以同步运行它(定义void Session_Start等),但它更喜欢异步方式,以便命中数据库不会阻塞.
使用'async Task' Session_Start执行此操作时,代码不会执行,内部session_start的断点不会被命中.
小智 7
根据我的理解,ASP有一个指定的线程,它是唯一可以访问该HttpContext.Current对象的线程,反过来,访问Session(HttpContext.Current.Session)就像在Windows应用程序中的UI线程一样.因此,执行.Wait()或.Result在Session_Start回调中将为您提供未知结果和/或使进程死锁.
似乎有很多方法来管理Task的执行线程,主要的方法是通过TaskScheduler类https://msdn.microsoft.com/en-us/library/system将您的任务指定为使用某个同步上下文运行. threading.tasks.taskscheduler(v = vs.110).ASPX#同步
但是,由于Task类被设计为实现IAsyncResult,它来自APM(异步编程模型)模式,这使得Task向后兼容旧的APM模式代码(根据我最初构建的ASP的理解).虽然https://blogs.msdn.microsoft.com/mazhou/2011/10/04/the-asynchronous-programming-models/(标准APM),但它需要一些集成工作.
.Net 4.5引入了一个很好的Task wrapper(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
}
Run Code Online (Sandbox Code Playgroud)
Global.asax 中的那些方法Session_Start很特殊。你不能随意定义新的。该框架运行其编程运行的框架,并且不提供异步版本。因此,不会运行任何异步版本。
然而,无论如何,异步其实并没有什么意义。Global.asax 方法在应用程序池启动和关闭时调用。因此,在任何时候放弃操作线程都是没有意义的,因为在它完成其工作之前不会发生任何其他事情。
我不完全确定你在做什么,但根据代码中的注释,听起来无论如何这都不是正确的地方。同样,此代码仅运行一次,而不是针对每个请求运行。如果您希望每个请求发生一些事情,请研究诸如操作过滤器之类的东西。
| 归档时间: |
|
| 查看次数: |
1606 次 |
| 最近记录: |