【问题标题】:Does linq block the thread?linq 会阻塞线程吗?
【发布时间】:2011-10-20 19:19:01
【问题描述】:

我正在将一些存储过程转换为 vb.net linq(SQL 到 linq .... 手动),因为存储过程很慢。

我在并发线程中使用 linq 查询。

运行性能分析后,我发现 linq 在查询时似乎锁定了源集合(如下面代码段中的 cache.IPMS_TBL_EL_PRICE_COMPONENT)。

这是真的吗? linq 是否有 (not_lock/lock) 选项? 我真的不希望收藏被锁定。它会减慢多线程查询。

非常感谢。

代码周期:

http://imgur.com/Z9vsR或见下文

insert0 = (From PPC In cache.IPMS_TBL_EL_PRODUCT_PRICE_COMPONENT_MAPPING
                           From PC In cache.IPMS_TBL_EL_PRICE_COMPONENT
                           Join LK In cache.IPMS_TBL_LOOKUP
                             On PC.Component_Type_Id Equals LK.Lookup_Id
                           Where (PC.Component_Id = PPC.Component_Id OrElse PC.Component_Type_Id = CC3_ID) _
                             AndAlso LK.Commodity_Id = ELE_COMMODITY_ID _
                             AndAlso LK.Lookup_Type.ToLower = PRICE_COMPONENT_TYPE.ToLower _
                             AndAlso PPC.Product_Id = IN_PRODUCT_ID _
                             AndAlso PPC.Price_Type_Id = IN_PRICE_TYPE_ID _
                             AndAlso PC.Is_Deleted = 0 _
                             AndAlso LK.Lookup_Id > MINUS_HUNDRED _
                             AndAlso PC.Component_Id > MINUS_HUNDRED _
                             AndAlso lookupValues.Contains(LK.Lookup_Value.ToLower) _
                             AndAlso (Not PC.ISO_Id.HasValue OrElse Not deletedISO.Contains(PC.ISO_Id.Value))
                           Select New PriceComponents() With {.ComponentID = PC.Component_Id,
                                                              .ComponentName = PC.Component_Name,
                                                              .ComponentTypeID = PC.Component_Type_Id,
                                                              .ComponentTypeName = LK.Lookup_Value,
                                                              .Sequence = PC.Sequence,
                                                              .OrderSequence = orderSequeceDict(LK.Lookup_Value.ToLower),
                                                              .IsMTM = PC.Is_MTM,
                                                              .UcapUsageFactorUnitPrice = PC.UCAP_Usage_Factor_UnitPrice,
                                                              .Percentage = PERCENTAGE}
                           ).OrderBy(Function(e As PriceComponents) e.OrderSequence).ThenBy(Function(e As PriceComponents) e.Sequence) _
                           .Distinct(New PriceComponentsComparer_PK_9_Fields).ToList

【问题讨论】:

  • 如果 cache 是一个 LINQ to SQL 数据上下文,那么它不应该在线程之间共享。
  • 让我们在这里稍微备份一下... 你知道为什么存储过程很慢吗?这是转换为 L2S 的一个不寻常的原因。 LINQ 查询是否执行您的存储过程?
  • 问题是关于阻塞(非延迟、同步执行)还是关于查询期间被锁定(防止多线程使用)的问题?这些是非常不同的事情。
  • @PeteM 是的。存储过程非常慢。它将 3 或 4 亿条记录的表连接在一起,运行时间为 10 分钟。一个名为 Cognizant 的大型公司编写了它并放入了一个三层循环。新的 linq 替换只需要 2 秒。
  • @jdv-JandeVaan:这是关于尽量不被 linq 阻塞。

标签: .net linq concurrency


【解决方案1】:

您正在调用ToList,这会导致查询急切地求值(当时)。

使用ToList,它将遍历返回请求结果的结果集——这确实会使用当前线程。

您可以通过不调用 ToList推迟评估,并且仅在您真正需要迭代结果时评估。

【讨论】:

  • 听起来很合理。我将建立一个简单的项目来测试这种方法。再等一个小时以获得更多答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
相关资源
最近更新 更多