在pLinq查询中使用会话状态

在pLinq查询中使用会话状态,linq,httpcontext,plinq,Linq,Httpcontext,Plinq,我有一个相当简单的Linq查询(简化代码): 产品是一个类。Price是一个子类,GrossPrice是它的属性之一。为了计算出价格,我需要使用Session(“汇率”) 因此,对于lstProductList中的每个项目,都有一个函数执行以下操作: NetPrice=NetPrice * Session("exchange_rate") (然后GrossPrice返回净价+增值税金额) 无论我尝试了什么,我都无法访问会话状态 我已经尝试了HttpContext.Current,但是没有返回任

我有一个相当简单的Linq查询(简化代码):

产品是一个类。Price是一个子类,GrossPrice是它的属性之一。为了计算出价格,我需要使用Session(“汇率”)

因此,对于lstProductList中的每个项目,都有一个函数执行以下操作:

NetPrice=NetPrice * Session("exchange_rate")
(然后GrossPrice返回净价+增值税金额)

无论我尝试了什么,我都无法访问会话状态

我已经尝试了HttpContext.Current,但是没有返回任何结果。 我曾尝试在类上实现IRequiresessionState(这在通用http处理程序[.ashx]中的类似情况下很有帮助)——运气不好

我使用的是简单的InProc会话状态模式。汇率必须是特定于用户的

我能做什么

我的工作对象是: web开发.NET4,VB.Net


一步一步:
页面加载(in.aspx)
dim objSearch as new SearchClass()
dim output=objSearch.renderProductsFound()

然后在objSearch.renderProductsFound:
lstProductList.Add(objProduct(1))

lstProductList.Add(objProduct(n))

dim x=来自lstProductList.aspallel中的产品
按产品订购。价格。降序选择产品

在Product.Price.GrossPrice Get中:
返回我.NetPrice+me.VatAmount

在Product.Price.NetPrice中获取:
返回NetBasePrice*会话(“汇率”)


同样,简化的代码,太多了,无法粘贴在这里。如果我将查询展开为For循环,则可以正常工作。

我不确定
HttpContext.Current
如何工作,但如果它只在处理HTTP请求的主线程上工作,我也不会感到惊讶。这意味着您不能在任何其他线程上使用它。当PLINQ执行查询时,它会从线程池中选择一些随机线程,并使用这些线程计算查询中的谓词,因此这可能是查询不起作用的原因

如果
GrossPrice
属性只需要从会话状态访问一件事,那么将其更改为方法并将会话状态的值作为参数传递应该相当容易:

Dim rate = Session("exchange_rate")
Dim x = From product In lstProductList.AsParallel  
        Order By product.Price.GetGrossPrice(rate) Descending 
        Select product 

根据您稍后使用
x
的位置,您还可以添加对
ToList
的调用,以强制执行查询的计算(否则它可能会在稍后的某个时间延迟执行),但我认为我上面描述的更改应该可以修复它。

我不确定
HttpContext.Current
是如何工作的,但是如果它只在处理HTTP请求的主线程上工作,我也不会感到惊讶。这意味着您不能在任何其他线程上使用它。当PLINQ执行查询时,它会从线程池中选择一些随机线程,并使用这些线程计算查询中的谓词,因此这可能是查询不起作用的原因

如果
GrossPrice
属性只需要从会话状态访问一件事,那么将其更改为方法并将会话状态的值作为参数传递应该相当容易:

Dim rate = Session("exchange_rate")
Dim x = From product In lstProductList.AsParallel  
        Order By product.Price.GetGrossPrice(rate) Descending 
        Select product 

根据您稍后使用
x
的位置,您还可以添加对
ToList
的调用,以强制对查询进行求值(否则可能会在稍后的某个时间延迟执行),但是我认为我上面描述的更改应该可以解决这个问题。

您应该真正从会话状态中读取值,并将其读入您知道在LINQ语句中需要的局部变量中。否则,当值基本上是常量时,您实际上每次都在为每个线程中的每个元素访问NameValueCollection实例。

您应该真正从会话状态中读取值,并将其读入LINQ语句中所需的局部变量中。否则,您实际上每次都在访问每个线程中每个元素的NameValueCollection实例,而该值基本上是常量。

您真的是这样写的吗?因为在使用之前,您需要将会话中的任何内容强制转换为适当的类型。不,这只是简化了。计算实际上要复杂得多,而且有很多检查,包括无检查、类型转换(在上面的例子中是CDec)和默认值。要了解HttpContext是否可用,请解释如何调用此代码。是从.aspx还是别的什么?jarrett,我在原始问题的末尾添加了一系列事件你能
回答.Write(会话(“汇率”)
?你真的是这样写的吗?因为在使用之前,您需要将会话中的任何内容强制转换为适当的类型。不,这只是简化了。计算实际上要复杂得多,而且有很多检查,包括无检查、类型转换(在上面的例子中是CDec)和默认值。要了解HttpContext是否可用,请解释如何调用此代码。是从.aspx还是别的什么?jarrett,我在原始问题的末尾添加了一系列事件。你能
回答吗?写(会话(“汇率”)
?托马斯,谢谢。关于并行线程不能访问HTTPContext和使用局部变量的问题,我的想法也是一样的,只是我以后需要将这个类序列化为JSON——这对方法不起作用。到目前为止,我最好的想法是将GrossPrice作为一个属性,将GetGrossPrice作为一个方法-将第一个用于序列化,并在pLinq中使用后者,必须有一个更雄辩的解决方案…Tomas,谢谢。关于并行线程不能访问HTTPContext和使用局部变量的问题,我的想法也是一样的,只是我以后需要将这个类序列化为JSON——这对方法不起作用。到目前为止,我最好的想法是将GrossPrice作为一个属性,将GetGrossPrice作为一个方法——将第一个用于序列化,将后一个用于