博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HttpContext.Current:异步模式下的疑似陷阱之源
阅读量:5983 次
发布时间:2019-06-20

本文共 3120 字,大约阅读时间需要 10 分钟。

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

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

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

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

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

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

但是,很多类库(包括MS自己的)的现有内部实现中都离不开HttpContext.Current,我这里并不是说类库中充斥着HttpContext.Current就是一种bad design。根据我个人的分析,至少目前已被广泛使用的内部实现,满满的都是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方法的内部逻辑的一部分或者当中的参数,我们还是能够理解的。

 

参考:

 

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

先看SignOut方法的代码:

SignOut      ///         /// Removes the forms-authentication ticket from the browser.        ///         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上问过这个问题,“”。

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

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

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

 

参考:

你可能感兴趣的文章
小白学Weex(一) —— 环境搭建
查看>>
用koa开发一套内容管理系统(CMS),支持javascript和typescript双语言
查看>>
Data Lake Analytics + OSS数据文件格式处理大全
查看>>
如何解决高并发,秒杀问题
查看>>
Spring 执行 sql 脚本(文件)
查看>>
①Windows Server 8基于远程桌面服务方案的安装
查看>>
( 译、持续更新 ) JavaScript 上分小技巧(三)
查看>>
ASP.NET 缓存(4)
查看>>
2015百度之星 单调区间
查看>>
循序渐进学Oracle之函数(重点)
查看>>
Oracle 11gR2构建RAC之(4)--安装GI
查看>>
项目经理之什么是项目管理
查看>>
Ubuntu安装Chrome的方法
查看>>
用批处理来操纵你的光驱
查看>>
SQL 问题记录
查看>>
第六章 对象作用域与servlet事件监听器
查看>>
vim修改时自动备份配置文件小脚本
查看>>
我的友情链接
查看>>
官宣:深度剖析免费OA系统是如何盈利
查看>>
vue2.0学习笔记(一)搭建学习环境
查看>>