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

闲暇之余再重新查查资料温故知新学习一遍,重新认识了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. PHP对redis操作详解【转】

    /*1.Connection*/ $redis = new Redis(); $redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超 ...

  2. NPOI创建DOCX常用操作【转】

    1.  创建文档 XWPFDocument m_Docx = new XWPFDocument();2.  页面设置 //1‘=1440twip=25.4mm=72pt(磅point)=96px(像素 ...

  3. DNS配置

    配置永久IP: cd  /etc/sysconfig/network-scripts/ 主DNS服务器配置: 由于caching-nameserver软件包提供了各种配置文件的模板,大大降低了BIND ...

  4. Win8.1下FreeImage.lib库的配置和简单使用(转)

    转自http://www.codeweblog.com/win8-1下freeimage-lib库的配置和简单使用/ 首先,你可以从这里获取FreeImage的完整库文件(访问密码 9a5e). 配置 ...

  5. zabbix利用mutt和msmtp配置邮件报警

    Mutt安装 yum –y install mutt msmtp安装 yum –y install openssl openssl-devel libntlm libntlm-devel cyrus- ...

  6. jquery 传递事件的自定义数据

    整理一下 1. <script type="text/javascript">$(document).ready(function(){  $("input& ...

  7. Object-C内存管理-对象引用计数的特例

    看到OC中内存管理这块,其中的引用计数部分,部分10.5上的EBOOK示例已经在10.9上不能运行正确了,比如下面的代码: NSString * str1 = @"string 1" ...

  8. berkeley db replica机制 - 消息处理

    repmgr_method.c, __repmgr_start_int()repmgr_method.c, __repmgr_start_msg_threads()repmgr_msg.c, __re ...

  9. 【转】Chrome快捷键

    感谢原作者:http://www.cnblogs.com/mikalshao/archive/2010/11/03/1868568.html 标签页和窗口快捷键 Ctrl+N 打开新窗口. Ctrl+ ...

  10. mottoes

    1. You don't kown if you can until a try. 2. Rule youself. 3. It's what you do in the dark that puts ...