gpt4 book ai didi

C#:在 ASP.NET 中向 Parallel.ForEach() 添加上下文

转载 作者:可可西里 更新时间:2023-11-01 08:23:05 26 4
gpt4 key购买 nike

我有一个带有静态 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
}

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

问题在于 Promotion 的静态构造函数,它是在 Parallel.ForEach() 中第一次创建 new Promotion() 时初始化的,使用 HttpContext.Current。当 promo 在此 Parallel.ForEach() 范围内实例化时,HttpContext.Currentnull,并且new Promotion() 因此导致异常。

HttpContext.Current 在静态 get 属性中不为空,因为在 View 使用它之前不会调用它(因此有一个 HttpContext.Current)。

如果 Promotion 在其实例中使用 HttpContext.Current 而不是静态成员,我可能只需将 HttpContext.Current 传递到 new Promotion() 构造函数:

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

但是由于 Promotion 的 static 成员需要 HttpContext.Current,所以我不能。我可能可以重新设计 Promotion 类,以将需要它的静态成员更改为实例成员,但它们是静态的是有原因的——如果所有成员都是静态的,将会有很大的性能损失每次实例化 new Promotion 时,都必须在每个实例上定义。

对此有哪些可能的解决方法?我没有意识到 HttpContext.CurrentParallel.ForEach() 的范围内会为 null。

最佳答案

HttpContext.Current 为空,因为它在“非网络线程”中运行。如果您使用 new Thread(...) fork 一些代码,它会完全一样。 TPL 在某种程度上隐藏了这一点,但您仍然需要意识到 Parallel.ForEach 中的每次迭代都可能在不同的线程中运行,并相应地对待它。

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

简而言之:您需要停止静态使用 HttpContext.Current。

关于C#:在 ASP.NET 中向 Parallel.ForEach() 添加上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3790817/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com