У меня есть блок кода, который обрабатывает StoreProducts, а затем добавляет или обновляет их в базе данных в a для каждого цикла. Но это медленно. Когда я конвертирую блок Parallel.ForEach в код, то те же самые продукты одновременно добавляются и обновляются. Я не мог понять, как безопасно использовать для следующих функций, любая помощь будет оценена по достоинству.Parallel.ForEach Список источников с Где Условие
var validProducts = storeProducts.Where(p => p.Price2 > 0
&& !string.IsNullOrEmpty(p.ProductAtt08Desc.Trim())
&& !string.IsNullOrEmpty(p.Barcode.Trim())
).ToList();
var processedProductCodes = new List<string>();
var po = new ParallelOptions()
{
MaxDegreeOfParallelism = 4
};
Parallel.ForEach(validProducts.Where(p => !processedProductCodes.Contains(p.ProductCode)), po,
(product) =>
{
lock (_lockThis)
{
processedProductCodes.Add(product.ProductCode);
}
// Check if Product Exists in Db
// if product is not in Db Add to Db
// if product is in Db Update product in Db
}
Дело здесь есть, список validProducts может иметь более чем одну такую же ProductCode, поэтому они являются вариантами, и я должен управлять, что даже один из них находится в процессе обработки он не должен быть обработан снова.
Так где условие, которое находится в параллельном Еогеасп «validProducts.Where (р =>! ProcessedProductCodes.Contains (p.ProductCode)» не работает, как ожидалось, как в обычном для каждого.
Вы также можете захотеть выполнить запрос «вставить или обновить» вместо проверки своего списка в памяти. В базах данных, которые не поддерживают это напрямую, вы можете обычно выполнять обновление, проверять # затронутых записей и вставлять, если 0 всего в одном запросе. Но я был бы очень обеспокоен блокировкой/блокировкой БД во время этого процесса (см. Мой ответ выше), особенно если выполняются другие рабочие нагрузки. –
@Scott Chamberlain благодарит вас за ваше время и ответ, я использовал разделитель, hashset и return (как вы указали, и я думаю, что это сделал трюк) все прошло гладко. – Buyukcaglar