摘要

HttpContext上下文并不是无处不在的。详情可以看下Fish Li的文章,解释的比较清楚。

HttpContext.Current并非无处不在

问题复现

        public async Task<ActionResult> Home()
{
return await Task.Factory.StartNew(() =>
{
var context = System.Web.HttpContext.Current;
System.Web.HttpContext context2 = System.Runtime.Remoting.Messaging.CallContext.HostContext as HttpContext;
return View();
});
}

比如有上面一段代码,你需要用到HttpContext,大部分人都会通过HttpContext.Current方式拿到当前请求的上下文。

但是

为什么拿不到上下文对象呢?

首先我们需要了解,HttpContext保存在哪儿?,在Fish Li的文章中已经说的很详细了,HttpContext其实是保存在CallContext.HostContext这个属性中的。

CallContext.HostContext

获取或设置与当前线程相关联的主机上下文。(MSDN)

当前线程: 当前线程是指与【当前请求】相关的线程。

其中Fish Li有这么段话解释的比较清楚

【当前线程】是个什么意思? 我为什么要突出这个词呢?

答:
1. 当前线程是指与【当前请求】相关的线程。
2. 在ASP.NET中,有些线程并非总是与请求相关。

感觉有点绕口吗? 不容易理解吗? 还是继续往下看吧。

虽然在ASP.NET程序中,几乎所有的线程都应该是为响应请求而运行的,
但是,还有一些线程却不是为了响应请求而运行,例如:
1. 定时器的回调。
2. Cache的移除通知。
3. APM模式下异步完成回调。
4. 主动创建线程或者将任务交给线程池来执行。

在以上这些情况中,如果线程执行到HttpContext.Current,您认为会返回什么?
还是一个HttpContext的实例引用吗?
如何是,那它与哪个请求关联?

显然,在1,2二种情况中,访问HttpContext.Current将会返回 null 。
因为很有可能任务在运行时根本没有任何请求发生。
了解异步的人应该能很容易理解第3种情况(就当是个结论吧)
第4种情况就更不需要解释了,因为确实不是当前线程。

猜测,task.factory.startnew,开启一个新的任务执行的。所以这里拿不到HttpContext也符合上述的情况。

那么我们可以在请求开始的时候可以通过变量将上下文保存起来,比如下面的方式。

总结

通过本篇文章,在异步中使用HttpContext.Current需要特别注意,它并不是无处不在的,所以在使用的时候,最好判断一下是否为null。

相关文章

Fish Li:HttpContext.Current并非无处不在

asp.net mvc中在使用async的时候HttpContext为null的问题的更多相关文章

  1. Asp.net mvc中的Ajax处理

    在Asp.net MVC中的使用Ajax, 可以使用通用的Jquery提供的ajax方法,也可以使用MVC中的AjaxHelper. 这篇文章不对具体如何使用做详细说明,只对于在使用Ajax中的一些需 ...

  2. ASP.NET MVC中使用异步控制器

    线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个 ...

  3. Asp.net mvc 中Action 方法的执行(一)

    [toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...

  4. Asp.net mvc 中的 Controller 的激活

    Controller 激活是指根据路由系统解析出来的 Controller 的名称创建 控制器(Controller)的过程,这里的控制器泛指实现了 IController 接口的类型 激活过程中的核 ...

  5. 在 ASP.NET MVC 中使用异步控制器

    线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个 ...

  6. ASP.NET Identity系列02,在ASP.NET MVC中增删改查用户

    本篇体验在ASP.NET MVC中使用ASP.NET Identity增删改查用户. 源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMV ...

  7. ASP.NET MVC中商品模块小样

    在前面的几篇文章中,已经在控制台和界面实现了属性值的笛卡尔乘积,这是商品模块中的一个难点.本篇就来实现在ASP.NET MVC4下商品模块的一个小样.与本篇相关的文章包括: 1.ASP.NET MVC ...

  8. ASP.NET MVC中设置跨域

    ASP.NET MVC中设置跨域 1.什么是跨域请求 js禁止向不是当前域名的网站发起一次ajax请求,即使成功respone了数据,但是你的js仍然会报错.这是JS的同源策略限制,JS控制的并不是我 ...

  9. js基础 js自执行函数、调用递归函数、圆括号运算符、函数声明的提升 js 布尔值 ASP.NET MVC中设置跨域

    js基础 目录 javascript基础 ESMAScript数据类型 DOM JS常用方法 回到顶部 javascript基础 常说的js包括三个部分:dom(文档document).bom(浏览器 ...

随机推荐

  1. 关于IOS时间日历的一些注意事项 NSDateFormatter

    1.时间或者日期格式化的格式化,在真机上运行的是hi,必须指定是在哪个区域的,不然在真机无法显示 // 1.日期格式化 NSDateFormatter *fmt = [[NSDateFormatter ...

  2. Linq Like

    Like的操作,有点像in,但是,方向变了.什么意思呢.就是你给定一个字符串,去寻找数据中某个字段包含这个字符串.就是给定的字符串是某字段的子集.Sql Script是这么写的. Selec * fr ...

  3. MySQL备份原则

      数据库备份遵守的原则: 定期对数据库进行备份 启用mysql服务器的二进制日志 备份文件命名既要有规律又要有意义 备份文件和数据库不要放在一个文件系统上 定期使用文件系统的备份功能来备份数据库的备 ...

  4. C#实现 Eval

    主要是使用 CSharpCodeProvider,动态调用来进行返回. 首先会拼接成一个类的一个方法,然后返回这个方法的值.不过,因为还是使用反射,所以效率不高. public static clas ...

  5. POJ 2533 Longest Ordered Subsequence(最长上升子序列(NlogN)

    传送门 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subseque ...

  6. 对iOS中Delegate的理解

    首先 协议protocol 和委托delegate 是两个完全不同的概念  放在一起说 是因为我们总是在同一个头文件里看到它们: 首先解释一下什么是委托 :举个例子 ,我工作的时候给你打电话,让你帮我 ...

  7. Socket与SocketServer结合多线程实现多客户端与服务器通信

    需求说明:实现多客户端用户登录,实现多客户端登录一般都需要使用线程技术: (1)创建服务器端线程类,run()方法中实现对一个请求的响应处理: (2)修改服务器端代码,实现循环监听状态: (3)服务器 ...

  8. vc++ 中 IntelliSense: 无法打开 源 文件 "xxx.h"

    类似无法找到文件的问题都可以用这个方法解决,就是路径的问题.vc++2008的项目转到vc++2010也可能出现类似的问题. 解决方法: 在  项目属性=>配置属性=>C/C++  =&g ...

  9. NSClassFromString 和 遍历UIView获取她所在的UIViewController的tips

    一.NSClassFromString是NSObjCRuntime.h的方法 FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString ...

  10. Diode -- Pay Attention to Parallel Connection

    The above circuit is right. The two same resistors are integral. Because every diode is different, t ...