Блокирует ли linq поток?

#.net #linq #concurrency

#.net #linq #параллелизм

Вопрос:

Я превращаю некоторую хранимую процедуру в vb.net linq (SQL для linq …. вручную), потому что хранимая процедура работает медленно.

Я использую запросы linq в параллельных потоках.

После выполнения анализа производительности я обнаружил, что linq, похоже, блокирует исходную коллекцию (например, кэш.IPMS_TBL_EL_PRICE_COMPONENT в приведенном ниже периоде кода) при запросе.

Это правда? Существует ли опция (not_lock / lock) для linq? Я действительно не хочу, чтобы коллекция была заблокирована. Это замедлит выполнение многопоточного запроса.

Большое вам спасибо.

Период кода:

смотрите в 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
  

Комментарии:

1. Если cache это контекст данных LINQ to SQL, то он не должен использоваться совместно между потоками.

2. Давайте вернемся немного назад… Вы выяснили, почему хранимая процедура была медленной? Это необычная причина для преобразования в L2S. Выполняет ли запрос LINQ вашу хранимую процедуру?

3. Вопрос о блокировке (не отложенное, синхронное выполнение) или о том, что блокируется (предотвращая многопоточное использование) во время запроса? Это очень разные вещи.

4. @PeteM да. Хранимая процедура работает чертовски медленно. Он объединит 3 или 4 таблицы с сотнями миллионов записей и потратит 10 минут на запуск. Какая-то гребаная компания под названием Cognizant написала это и ввела трехуровневый цикл. Замена нового linq занимает всего 2 секунды.

5. @jdv-JandeVaan: речь идет о попытке не блокировать linq.

Ответ №1:

Вы вызываете ToList , что заставляет запрос с нетерпением оценивать (там и тогда).

При ToList этом он будет перебирать результирующий набор, возвращая запрошенные результаты — это действительно будет использовать текущий поток.

Вы можете отложить оценку, не вызывая ToList и оценивая только тогда, когда вам действительно нужно выполнить итерацию по результатам.

Комментарии:

1. Звучит разумно. Я создам простой проект для тестирования этого подхода. жду еще час для получения дополнительных ответов. Спасибо.