C#异步,多线程下的HttpContext丢失问题
1、思路概述
首先让我把大概的一个思路先说一遍吧。
我在一个页面中要同时调用两个接口,而我要给这些接口一些参数:就是我通过HttpContext.Current.Request.QueryString获取的URL地址上的参数。因为由于特殊需要,我需要把这写参数全部放到一个类中,然后让Page页面继承就可以直接调用其中的属性了。然后接受返回的参数,由于这两者的接口内部处理的比较复杂,做的处理比较多,再者我之前也是一直在学习,也看了博客园里写的一些知识,我想学以致用!:-)
是什么方法?当然是随处可见的异步了,异步的好处相信大家都知道!其中,经常挂在嘴边的就是增加吞吐量。至于异步是什么,博客园里面讲的好的太多了!我就不在这里赘述了。既然想到了那就立马执行
2、代码描述
首先是把URL上的parameter写到一个继承自Page类NewRulePage类:
public class NewRulePage : System.Web.UI.Page
{
public string Asid
{
get
{
string p = MyRequest.GetQueryString("adsid");
if (string.IsNullOrEmpty(p))
{
return "";
}
return p;
}
}
public string Aid
{
get
{
string a = MyRequest.GetQueryString("a");
if (string.IsNullOrEmpty(a))
{
return "";
}
return a;
}
}
...
}
接着是触发调用接口事件(其他无关紧要的代码忽略不看)
protected void Btn_submit_Click(object sender, EventArgs e)
{
...
Action<int, string, string, string, string> pa_func = SelectPaService;
//开始异步
var context = HttpContext.Current;
IAsyncResult async = pa_func.BeginInvoke(newid, IP, xfw, rep, cityid, null, null);
pa_func(newid, IP, xfw, rep, cityid);
SelectSsService(newid, IP, xfw, rep);
pa_func.EndInvoke(async);
//异步结束
...
}
//调用接口1
private void SelectPaService(int newid, string IP, string xfw, string rep, string cityid)
{
//一系列的调用NewRulePage的属性的操作
...
}
//调用接口2
private void SelectSsService(int newid, string IP, string xfw, string rep)
{
//一系列的调用NewRulePage的属性的操作
...
}
3、出现问题
结果运行发现报错:未将对象引用设置到对象的实例
有趣的事还在后面,当我继续往下断点调试的时候,在异步期间的SelectSsService方法却能正常执行并得到返回结果,而SelectSsService这个方法也是获取URL参数。那为什么不同样报错呢?为什么HttpContext这个对象会在SelectPaService方法中不存在?这个Http上下文不应该”处处可见“么?百般无奈,我只好带着这些疑问在万能的度娘搜索一下看有没有解释的,无奈,讲HttpContext不少,但是这方面的却不多!囧
无奈,自己处理吧!!原理我先丢着暂时不管,咱遇到什么问题就解决什么问题;Go Go Go
4、解决问题
现在的问题是什么?
自然是在SelectPaService方法中HttpContext丢失了,那么我想办法恢复HttpContext不就行了吗?或者伪造一个?(说法不好 哈哈~) IAsyncResult异步我们知道,实质上其实就是izai运行期间开启了两个线程工作,所以我们可以将上面异步改成线程模式调用来说明问题:
Thread thread = new Thread(new ThreadStart(delegate(){
SelectPaService(newid, IP, xfw, rep, cityid);
}));
ta.Start();
SelectSsService(newid, IP, xfw, rep);
毫无疑问,出现一样的错误,主线程中能访问HttpContext,而子线程的丢失了,虽然如此,之前我说了,可以恢复一个或伪造一个!最直接的办法怎么做?我想你们应该都知道了,就是直接在异步(子线程开启之前)给调用的方法传一个HttpContext对象不就有了么? 为了印证想法,我还是运行一下:
Action<int, string, string, string, string, HttpContext> pa_func = SelectPaService;
////开始异步
var context = HttpContext.Current;
IAsyncResult async = pa_func.BeginInvoke(newid, IP, xfw, rep, cityid, context, null, null);
pa_func(newid, IP, xfw, rep, cityid, context);
SelectSsService(newid, IP, xfw, rep);
pa_func.EndInvoke(async);
运行结果一切OK!!!!值得高兴~~~∩_∩
5、原理补充说明
虽说问题解决了,但是不知道原理,下次出了一个类似的问题估计还是够吃力!所以想在园子里找找有没有讲这方面的。结果还真找到我需要的了(搜索关键字很重要啊~~~o(︶︿︶)o ),再此来分享一下:fish-li大神的文章:HttpContext.Current并非无处不在 这里就详细讲了为什么会丢失,以及怎么做(里面就讲到了我现在用的通过传参的方式)~~顺便再次膜拜一下园子里的大神们!!! Over~
C#异步,多线程下的HttpContext丢失问题的更多相关文章
- ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 349人阅读 评论(0) 收藏
问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...
- ASP.NET多线程下使用HttpContext.Current为null解决方案 2015-01-22 15:23 350人阅读 评论(0) 收藏
问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...
- ASP.NET多线程下使用HttpContext.Current
本来要实现asp.net下使用tcp通讯方式向服务器获取数据,开始采用的方式是 参考: ASP.NET多线程下使用HttpContext.Current为null解决方案 http://www.cnb ...
- ASP.NET多线程下使用HttpContext.Current为null解决方案
多线程或者异步调用中如何访问HttpContext? 前面我还提到在APM模式下的异步完成回调时,访问HttpContext.Current也会返回null,那么此时该怎么办呢? 答案有二种:1. 在 ...
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...
- 初探.net framework 下的异步多线程
初探.net framework 下的异步多线程 目录 1.多线程的出现条件 2.Thread和ThreadPool的相关Api及用法 3.Task和Parallel的相关Api及用法 4.Async ...
- .NET 异步多线程,Thread,ThreadPool,Task,Parallel,异常处理,线程取消
今天记录一下异步多线程的进阶历史,以及简单的使用方法 主要还是以Task,Parallel为主,毕竟用的比较多的现在就是这些了,再往前去的,除非是老项目,不然真的应该是挺少了,大概有个概念,就当了解一 ...
- NET 异步多线程,THREAD,THREADPOOL,TASK,PARALLEL
.NET 异步多线程,THREAD,THREADPOOL,TASK,PARALLEL,异常处理,线程取消 今天记录一下异步多线程的进阶历史,以及简单的使用方法 主要还是以Task,Parallel为主 ...
- .NET异步多线程,Thread,ThreadPool,Task,Parallel,异常处理,线程取消
今天记录一下异步多线程的进阶历史,以及简单的使用方法 主要还是以Task,Parallel为主,毕竟用的比较多的现在就是这些了,再往前去的,除非是老项目,不然真的应该是挺少了,大概有个概念,就当了解一 ...
随机推荐
- winform NPOI excel 导出并选择保存文件路径
public void ExcelOp(DataGridView gdv,ArrayList selHead) { if (selHead.Count==0) { MessageBox.Show(&q ...
- .net core初试 --- 控制台程序
.net core这个名字对.net程序员来说都不陌生了,但貌似圈子里真正有开发经验的并不多,关键是公司的项目没需求. 今天我就趁着不忙上手玩了玩,搞明白了一些东西,心中也有了十万个为什么.那么现在与 ...
- NPOI 导出excel 通用方法
public static byte[] ExportExcel<T>(Dictionary<string, string> columnsHeader, List<T& ...
- Day 11 作业题
1.整理装饰器的形成过程,背诵装饰器的固定格式 固定格式 def wrapper(func): def inner(*args, **kwargs): #执行函数前进行的操作 ret = func(* ...
- FFMpeg的一些基础配置
一 . CMakeLists.txt文件的使用 1.添加头文件的相对路径 : include_directories(include(这里面就是文件的名字)) 2.设置ffmpeg的库的路径(v7a或 ...
- 1.python的一些规范
Python的一些规范 1.标识符 定义:允许作为名字的有效字符串集合 名字必须有实际意义,可读性好 首字母必须是字母或下划线(_) 剩下的字符可以是字母和数字或者下划线 大小写敏感 两种风格:con ...
- java实现简单扫雷游戏
/** * 一个简单的扫雷游戏 MainFram.java */ package www.waston; import java.awt.BorderLayout; import java.awt.C ...
- h5在线1v1客服|web在线客服系统|h5即时聊天
网上有很多环信.美恰之类的客服系统,最近也使用h5+css3+fontJs+swiper+wcPop等技术架构开发了一个在线客服(1v1沟通聊天),可以应用到在线临时聊天.在线咨询等情景.实现了消息. ...
- HTML页面的重绘(repaint)和重流(reflow)
重流(Reflow)是指布局引擎为frame计算图形的过程. frame是一个矩形,拥有宽高和相对父容器的偏移.frame用来显示盒模型(content model), 但一个content mode ...
- spring boot整合RabbitMQ(Direct模式)
springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. Direct Excha ...