HttpContext.Current:异步模式下的疑似陷阱之源

简介:

最近园子里首页有好几篇文章都是讲异步编程的,尤其是几篇讲博客园自身的异步化建设的文章,看了以后很有收获。

闲暇之余再重新查查资料温故知新学习一遍,重新认识了SynchronizationContext、AspNetSynchronizationContext和ConfigureAwait

最大的心得是,web异步化处理后,容易引发问题的一个重要方面就是请求上下文,也就是本文标题里的HttpContext.Current。

园子里fish-li写过一篇HttpContext.Current并不是无处不在,写的比较详细深入,看过这篇文章你就会非常明确用了HttpContext.Current容易引发哪些问题了。

记得很早以前开发某项目,引入了一个外部日志组件,反汇编之后竟然发现有直接通过HttpContext.Current获取IP、UserAgent、请求参数等信息的,当时就对同事说千万不要在异步逻辑里调用这个组件里的任何记录日志的方法,防止触雷。

我的观点是,不要轻易在任何地方(类库)使用HttpContext.Current,因为它并非无处不在,尽量把HttpContext的当前请求对象保留起来,可以传参或者供外部类库回调时重新获取请求上下文使用。

但是,很多类库(包括MS自己的)的现有内部实现中都离不开HttpContext.Current,我这里并不是说类库中充斥着HttpContext.Current就是一种bad design。根据我个人的分析,至少目前已被广泛使用的FormsAutentication内部实现,满满的都是HttpContext.Current充斥其中,而且最核心的读写cookie的方法都依赖HttpContext.Current。如果完全适应各种异步场景,说不定也会碰到HttpContext.Current不灵的情况,目测还有可优化的空间^_^。

我们所熟悉的aspx,ascx,ashx,masterpage,MvcHandler,MvcRouteHandler和MvcHttpHandler等等,每一个类实现的背后都有Httpcontext的存在,是否也有HttpContext.Current这种暴力写法?据我所知,反正Page类是有的。好奇查看了一下MVC3的源码,搜索关键字“HttpContext.Current”,整个MVC3源码匹配的行数为12行,MvcHandler和MvcHttpHandler确实有HttpContext.Current的出现,它最终作为ProcessRequest或BeginProcessRequest方法的内部逻辑的一部分或者当中的参数,我们还是能够理解的。

 

参考:

http://www.cnblogs.com/cmt/p/configure_await_false.html

http://www.cnblogs.com/jesse2013/p/Asynchronous-Programming-In-DotNet.html

http://www.cnblogs.com/fish-li/archive/2013/04/06/3002940.html

http://msdn.microsoft.com/zh-cn/magazine/jj991977.aspx

http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

 

附:在FormsAuthentication的SignOut方法中设置cookie过期时间的故事

先看SignOut方法的代码:

SignOut

 

注意设置过期时间httpCookie.Expires = new DateTime(1999, 10, 12);这一行,是不是很好奇想问为什么设置为1999年10月12号?设置过期时间的方式有多种,为什么写死这个魔幻时间,这个魔幻时间从哪里来的?

其实早在数年前就有人在stackoverflow上问过这个问题,“What's the significance of Oct 12 1999?”。

只要抛出问题,世上热心的好汉何其多哉,能准确回答的,不能确切回答的,还有小道消息道听途说的……

目前该问题已经关闭,共有12个可选答案,其中不乏有大神Scott Hanselman的回答,但最被推崇的竟然是排在Scott Hanselman后的那个说法,讲的煞有介事头头是道,就看你信哪个了。

我的另一最大收获是,原来NBA传奇球星张伯伦大帅卒于1999年10月12号。









本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/p/httpcontext_current-is-the-suspected-trap-source-of-aspnet-async-mode.html,如需转载请自行联系原作者

目录
相关文章
|
5月前
|
应用服务中间件
执行 ABAP 代码出现超时的原因,背后的理论和解决方案
:执行 ABAP 代码出现超时的原因,背后的理论和解决方案
|
应用服务中间件 数据安全/隐私保护
session 生命周期和经典案例-防止非法进入管理页面
session 生命周期和经典案例-防止非法进入管理页面
128 0
|
架构师 Java 编译器
抽丝剥茧聊协程之深入理解Continuation原理
抽丝剥茧聊协程之深入理解Continuation原理
抽丝剥茧聊协程之深入理解Continuation原理
|
Web App开发 缓存 前端开发
谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?
有时我们能在Chrome开发者工具的Network tab里观察到SAP UI5应用会发出某些状态为"取消"的OData请求。如下图第五个请求。 之前有一种似是而非的说法:极短时间内发送两个OData请求,则第一个会自动被cancel掉。
谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?
【观点】清除代码异味
译文出自:外刊IT评论
725 0
|
Windows
艾伟:WCF从理论到实践(15):响应变化
本系列文章导航 WCF从理论到实践(1):揭开神秘面纱 WCF从理论到实践(2):决战紫禁之巅 WCF从理论到实践(3):八号当铺之黑色契约 WCF从理论到实践(4):路在何方 WCF从理论到实践(5):Binding细解 WCF从理论到实践(6):WCF架构 WCF从理论到实践(7):消息交换模式...
1200 0
|
存储 缓存 Java
无声的性能杀手-伪共享(false-sharing)
# 前言 在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素。这段时间学习Log4j2解除到了Disruptor,它被誉为“最快的消息框架”,其LMAX架构能够在一个线程里每秒处理6百万订单!在讲到 Disruptor 为什么这么快时,接触到了一个概念——伪共享(false sharing),其中提到:缓存行上
2653 0