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方法的代码:

 /// <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);
    }
}
GarsonZhang www.yesdotnet.com

 

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

 

来自 <https://www.cnblogs.com/jeffwongishandsome/p/httpcontext_current-is-the-suspected-trap-source-of-aspnet-async-mode.html>

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
YES开发框架
上一篇:SAP hana 接口API使用Postman请求时签名处理,自动签名脚本
下一篇:慎用System.Web.HttpContext.Current
评论列表

发表评论

评论内容
昵称:
关联文章

HttpContext.Current异步模式陷阱
慎用System.Web.HttpContext.Current
Task 使用详细[基础操作,异步原则,异步函数,异步模式]
.Net 高性能分表分库组件-连接模式原理
C# NPOI导出excel绑定列拉数据
单表演练产品资料,辅助组件ViewDataBinding模式
重新认识Docker ComposeSidecar模式
vue中异步函数async和await用法
C# 从做早餐看同步异步
数据绑定模式
支付宝:当面付支付完成异步回调
2.网络聊天程序三种模式
.net异步Task转同步
Javascript 中通过 yield 和 promise 使异步变同步
AgileConfig-1.5.5 发布 - 支持 JSON 编辑模式
C# WPF MVVM模式Prism框架从零搭建(经典)
wifnorm处于设计模式校验 (.NET6)
在 SA 和 Windows 等账户都被禁用情况如何登录?
WindowsGit多账号配置,同一电脑多个ssh-key管理
【C#】C#中使用GDAL3(三):Windows编译插件驱动

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码