Sni*_*ave 12 c# asp.net parallel-processing multithreading
我有一个带静态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
}
Run Code Online (Sandbox Code Playgroud)
在视图使用此属性之前,此静态类不会进行类型初始化.
问题是,Promotion的静态构造函数,初始化第一次new Promotion()被内创建Parallel.ForEach(),使用HttpContext.Current.何时promo在此范围内实例化Parallel.ForEach(),HttpContext.Current是null,new Promotion()因此导致异常.
HttpContext.Current静态get属性中不为null,因为在视图使用它之前不会调用它(因此有一个HttpContext.Current).
如果Promotion使用HttpContext.Current在它的实例,而不是它的静态成员,我很可能只是传递HttpContext.Current到new Promotion()构造函数:
var context = HttpContext.Current;
Parallel.ForEach(files, file =>
{
var promo = new Promotion(context);
});
Run Code Online (Sandbox Code Playgroud)
但由于staticPromotion的成员需要HttpContext.Current,我不能.我可能会重新设计Promotion类来将需要它的静态成员更改为实例成员,但它们是静态的 - 如果所有静态成员都必须在每个实例上定义,那么会有很大的性能损失每次a new Promotion实例化.
有什么可行的解决方法?我没有意识到HttpContext.Current在范围内会无效Parallel.ForEach().
Mau*_*fer 11
HttpContext.Current为null,因为它在"非Web线程"中运行.如果你使用new Thread(...)它分叉一些代码就完全一样了.TPL在某种程度上隐藏了这一点,但您仍然需要意识到您的每个迭代Parallel.ForEach都可能在不同的线程中运行,并相应地对其进行处理.
特别是,如果你想在web请求中使用某些类或方法(并且Parallel.ForEach就是这种用法),你就是不能使用HttpContext.Current.解决方法是在构造函数中显式传递HttpContext(或HttpContextBase以提高可测试性)(或作为方法参数)
简而言之:你需要静态地使用HttpContext.Current.