zoukankan      html  css  js  c++  java
  • 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~

  • 相关阅读:
    微信小程序,搜索结果关键词高亮 wxml不能动态识别html标签
    关于vue 全局loading方案
    element ui树样式问题
    Promise.all( ) 的使用
    关于form表单校验问题
    vue 异步改同步 获取结果 动态函数
    1.关于数据for循环不要用index作为key,2.面二次刷新404问题(空白) 的探讨 3. vue图片上传
    element ui点击切换皮肤
    关于element ui input、以及button样式不能覆盖的解决办法(登录页面)
    vue版本根据当前路由匹配到根父节点并且激活
  • 原文地址:https://www.cnblogs.com/ms27946/p/4961560.html
Copyright © 2011-2022 走看看