Entity Framework и Parallel.Foreach [duplicate]

Сложная сравнительная работа:

len(set(the_list)) == 1

Использование set удаляет все повторяющиеся элементы.

19
задан casperOne 10 October 2012 в 21:44
поделиться

3 ответа

EF не является потокобезопасным, поэтому вы не можете использовать Parallel.

Взгляните на Entity Framework и многопоточность

и этот статья .

5
ответ дан Community 18 August 2018 в 07:06
поделиться

Это то, что я использую и отлично работаю. Он дополнительно поддерживает обработку исключений ошибок и имеет режим отладки, который значительно облегчает отслеживание вещей вниз

public static ConcurrentQueue<Exception> Parallel<T>(this IEnumerable<T> items, Action<T> action, int? parallelCount = null, bool debugMode = false)
{
    var exceptions = new ConcurrentQueue<Exception>();
    if (debugMode)
    {
        foreach (var item in items)
        {
            try
            {
                action(item);
            }
            // Store the exception and continue with the loop.                     
            catch (Exception e)
            {
                exceptions.Enqueue(e);
            }
        }
    }
    else
    {
        var partitions = Partitioner.Create(items).GetPartitions(parallelCount ?? Environment.ProcessorCount).Select(partition => Task.Factory.StartNew(() =>
        {
            while (partition.MoveNext())
            {
                try
                {
                    action(partition.Current);
                }
                // Store the exception and continue with the loop.                     
                catch (Exception e)
                {
                    exceptions.Enqueue(e);
                }
            }
        }));
        Task.WaitAll(partitions.ToArray());
    }
    return exceptions;
}

. Вы используете его так, как показано ниже, где db - это исходный DbContext и db.CreateInstance ( ) создает новый экземпляр, используя ту же строку соединения.

        var batch = db.Set<SomeListToIterate>().ToList();
        var exceptions = batch.Parallel((item) =>
        {
            using (var batchDb = db.CreateInstance())
            {
                var batchTime = batchDb.GetDBTime();
                var someData = batchDb.Set<Permission>().Where(x=>x.ID = item.ID).ToList();
                //do stuff to someData
                item.WasMigrated = true; //note that this record is attached to db not batchDb and will only be saved when db.SaveChanges() is called
                batchDb.SaveChanges();        
            }                
        });
        if (exceptions.Count > 0)
        {
            logger.Error("ContactRecordMigration : Content: Error processing one or more records", new AggregateException(exceptions));
            throw new AggregateException(exceptions); //optionally throw an exception
        }
        db.SaveChanges(); //save the item modifications
2
ответ дан realstrategos 18 August 2018 в 07:06
поделиться

Немного сложно устранить эту проблему, не зная, каков результат внутреннего исключения, если таковой имеется. Это может быть просто проблемой, связанной с настройкой строки подключения или конфигурации поставщика.

В общем, вы должны быть осторожны с параллельным кодом и EF. Однако то, что вы делаете, должно работать. Один вопрос в моем уме; Выполняется ли какая-либо работа над другим экземпляром этого контекста перед параллелью? Согласно вашему сообщению, вы делаете отдельный контекст в каждом потоке. Это хорошо. Однако часть меня удивляется, если между несколькими контекстами происходит интересное соперничество конструктора. Если вы не используете этот контекст где-либо перед этим параллельным вызовом, я бы предложил попытаться запустить даже простой запрос против контекста, чтобы открыть его и убедиться, что все биты EF запущены перед запуском параллельного метода. Я признаю, что я не пробовал точно , что вы здесь делали, но я сделал близко, и это сработало.

0
ответ дан to11mtm 18 August 2018 в 07:06
поделиться
  • 1
    вы знаете, что этот вопрос был опубликован в 2012 году, не так ли? – Claies 20 March 2015 в 02:13
Другие вопросы по тегам:

Похожие вопросы: