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

闲暇之余再重新查查资料温故知新学习一遍,重新认识了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      /// <summary>
/// Removes the forms-authentication ticket from the browser.
/// </summary>
public static void SignOut()
{
FormsAuthentication.Initialize();
HttpContext current = HttpContext.Current;
bool flag = current.CookielessHelper.DoesCookieValueExistInOriginal('F');
// Always clear the uri-cookie
current.CookielessHelper.SetCookieValue('F', null);
if (!CookielessHelperClass.UseCookieless(current, false, FormsAuthentication.CookieMode) || current.Request.Browser.Cookies)
{
string value = string.Empty;
if (current.Request.Browser["supportsEmptyStringInCookieValue"] == "false")
{
value = "NoCookie";
}
HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, value);
httpCookie.HttpOnly = true;
httpCookie.Path = FormsAuthentication._FormsCookiePath;
//What's the significance of Oct 12 1999
httpCookie.Expires = new DateTime(1999, 10, 12);
httpCookie.Secure = FormsAuthentication._RequireSSL;
if (FormsAuthentication._CookieDomain != null)
{
httpCookie.Domain = FormsAuthentication._CookieDomain;
}
current.Response.Cookies.RemoveCookie(FormsAuthentication.FormsCookieName);
current.Response.Cookies.Add(httpCookie);
}
if (flag)
{
current.Response.Redirect(FormsAuthentication.GetLoginPage(null), false);
}
}

注意设置过期时间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号。

参考:http://stackoverflow.com/questions/701030/whats-the-significance-of-oct-12-1999

HttpContext.Current:异步模式下的疑似陷阱之源的更多相关文章

  1. SQL Server AlwaysON 同步模式的疑似陷阱

    原文:SQL Server AlwaysON 同步模式的疑似陷阱 SQL Server 2012 推出的最重要的功能之一Alwayson,是一个集之前Cluster和Mirror于一体的新功能,即解决 ...

  2. 业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份

    业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份 WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多.大家对我做的这个行业 ...

  3. Log4j2异步情况下怎么防止丢日志的源码分析以及队列等待和拒绝策略分析

    org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor以下所有源码均在此类中首先我们看下log4j2异步队列的初始化 从这里面我们 ...

  4. Ansible系列(七):执行过程分析、异步模式和速度优化

    本文目录:1.1 ansible执行过程分析1.2 ansible并发和异步1.3 ansible的-t选项妙用1.4 优化ansible速度 1.4.1 设置ansible开启ssh长连接 1.4. ...

  5. ASP.NET多线程下使用HttpContext.Current为null解决方案

    多线程或者异步调用中如何访问HttpContext? 前面我还提到在APM模式下的异步完成回调时,访问HttpContext.Current也会返回null,那么此时该怎么办呢? 答案有二种:1. 在 ...

  6. 异步 HttpContext.Current 为空null 另一种解决方法

    1.场景 在导入通讯录过程中,把导入的失败.成功的号码数进行统计,然后保存到session中,客户端通过轮询显示状态. 在实现过程中,使用的async调用方法,出现HttpContext.Curren ...

  7. ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 349人阅读 评论(0) 收藏

    问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...

  8. ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 350人阅读 评论(0) 收藏

    问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...

  9. ASP.NET多线程下使用HttpContext.Current

    本来要实现asp.net下使用tcp通讯方式向服务器获取数据,开始采用的方式是 参考: ASP.NET多线程下使用HttpContext.Current为null解决方案 http://www.cnb ...

随机推荐

  1. linux命令连接远程服务器

    ssh root@IP    ***连接远程ip cd 路径           ***进入指定路径 ll                   ***查看当前文件 ll -a             ...

  2. C# Susan边缘检测(Susan Edge Detection)

    Susan边缘检测,方法简单,效率高,具体参照 The SUSAN Edge Detector in Detail, 修改dThreshold值,可以改变检测效果,用参照提供的重心法.力矩法可得到边缘 ...

  3. mysql5.6.34-debug Source distribution编译的几个错误

    raspberrypi下编译mysql5.6 debug版源码. 1. 启动错误 和mysqld相关的文件及文件夹权限必须设置为mysql用户可读可写可执行!谨记! 2. gdb错误 root@: g ...

  4. Oracle学习指南

    Oracle学习指南 你走的那天,我决定不落泪,迎着风撑着眼帘用力不眨眼 创建数据库.创建用户.创建表空间.创建表.插入数据..... 1.用系统用户登录,任选系统用户 代码: >>sql ...

  5. 解决mac安装grunt时出现[command not found]的错误

    第一步: 1先确定一下.bash_profile是否存在. 2在mac终端输入: test -e .bash_profile && echo "found" || ...

  6. iis6|iis7|配置URLRewriter|64位操作系统下|.net2.0|.net4.0|配置URLRewriter|Web.config配置详情

    想必很多ASP.NET的码友们在IIS配置伪静态被严重纠结过不止一次两次,本园主经过多次站点伪静态配置,总结了一下,IIS版本:IIS 6.IIS 7,服务器:Windows Server 2003. ...

  7. 在 Mac OS X 上创建的 .NET 命令行程序访问数据库 (使用Entity Framework 7 )

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  8. SCRUM站立会议

    SCRUM站立会议是让团队成员每日面对面站立互相交流他们所承担任务的进度.它的一个附带好处是让领导或经理能了解 到工作情况.本质上是为了团队交流,不是报告会议! 功能: 1)创造团队成员相互沟通的条件 ...

  9. M1M2总结

    这个学期很开心可以和一帮兄弟姐妹们一起做软件写代码,总体看下来真的是充满哦了艰辛和困苦.虽然我是负责软件测试的这一块的,但是看着他们辛苦的写代码我也很是为他们着急和心疼.毕竟,编译当头,数据库辅助,每 ...

  10. Java学习日记之 Java-其他类型

    OK , 就绪, 第一篇博客开撸 ~ 先听了毕姥爷激情澎湃的其他类型 ,从这里开始入手吧 : (一)System类  System类代表系统类,系统的属性和方法都放在该类.System类是一个fina ...