代码之家  ›  专栏  ›  技术社区  ›  SnickersAreMyFave

C#:添加上下文到并行循环()英寸ASP.NET

  •  12
  • SnickersAreMyFave  · 技术社区  · 14 年前

    我有一个带有static get属性的静态类,在这个属性中,我执行以下操作:

    // property body
    {
        // HttpContext.Current is NOT null
        ...
    
        Parallel.ForEach(files, file =>
        {
            // HttpContext.Current is null
            var promo = new Promotion();
            ...
        });
        ...
    
        // HttpContext.Current is NOT null
    }
    

    在视图使用此属性之前,此静态类不会进行类型初始化。

    问题是 Promotion 的静态构造函数,该构造函数在 new Promotion() Parallel.ForEach() ,使用 HttpContext.Current promo 在此范围内实例化 并行循环() , HttpContext.当前 null ,和

    HttpContext.当前 在静态get属性中不为null,因为在视图使用它之前不会调用它(因此存在 HttpContext.当前

    如果 促销 HttpContext.当前 在它的实例中,而不是在它的静态成员中,我可能只是传递 HttpContext.当前 进入 新促销() 施工单位:

     var context = HttpContext.Current;
     Parallel.ForEach(files, file =>
     {
         var promo = new Promotion(context);
     });
    

    但是自从 static 促销 new Promotion

    可能的解决方法是什么?我不知道 将在的范围内为null 并行循环() .

    4 回复  |  直到 14 年前
        1
  •  11
  •   Mauricio Scheffer    14 年前

    HttpContext.当前为空,因为它正在“非web线程”中运行。如果你用 new Thread(...) 完全一样。TPL在某种程度上隐藏了这一点,但是您仍然需要认识到,您的系统中的每个迭代 Parallel.ForEach 可以在不同的线程中运行,并相应地处理它。

    特别是,如果您想使用web请求之外的某个类或方法(以及平行.ForEach是这样的用法)你就是不能用HttpContext.当前. 一种解决方法是在构造函数中显式传递HttpContext(或HttpContextBase以提高可测试性)(或作为方法参数)

    简而言之:你需要摆脱使用HttpContext.当前静态的。

        2
  •  4
  •   mmmeff    11 年前

    把你从外部得到的任何信息传递出去平行.ForEach向下调用到依赖于所述上下文的内部调用的任何函数中。

    var context = HttpContext.Current;
    Parallel.ForEach(items, item =>
        {
            DoSomething(item, context);
        }
    );
    
    
    
    private static void DoSomething(item, context = null) {
        if (context == null) context = HttpContext.Current;
    
        ...
    }
    

        3
  •  0
  •   user180326 user180326    14 年前

    HttpContext.Current 取决于当前正在执行的线程。我觉得很不寻常 静态构造函数 取决于这样一个固有的瞬态值 HttpContext.当前 ,但也许那不是你的主意。

    如果你能改变 Promotion 这是我要考虑的第一个选择。

    促销 仍然有效。要了解什么强制类型初始化,请阅读 this Jon Skeet blog post

    可以选择创建一个虚拟对象 促销

        4
  •  0
  •   germensinho    9 年前

    它不起作用,因为在foreach中创建了一个新线程,因此上下文为null。即使创建一个DoSomething方法来设置curren上下文,上下文仍然是空的。