LINQ - Должен ли я как-то периодически отправлять SubmitChanges (), если у меня много изменений? - PullRequest
2 голосов
/ 23 августа 2011

У меня есть группа «роботов», которые бегают вокруг чтения RSS-потоков и сохраняют результаты в базе данных, и я распараллелил это так, чтобы можно было получать сразу несколько каналов:

Parallel.ForEach(context.Feeds, feed => ProcessRssFeed(feed, context));
context.SubmitChanges();

Функция ProcessRssFeed может вставлять записи в контекст по мере их обнаружения, и каждый фид может содержать от нуля до сотен элементов. Существует много каналов, поэтому я не хотел создавать LINQ DataContext для каждого.

Однако я беспокоюсь, что я могу накапливать тысячи и тысячи записей на клиенте. Я полагаю, мне не хватит памяти.

Поскольку здесь нет проблемы с параллелизмом, если бы это было возможно, я бы хотел сказать DataContext: «Продолжайте и периодически отправляйте записи, если хотите». Есть ли практический способ добиться этого?

Ответы [ 2 ]

3 голосов
/ 23 августа 2011

Я бы рекомендовал создать новый DataContext для каждого. DataContexts довольно легки по сравнению с фактическим подключением к базе данных. DataContext использует пул соединений при соединении с базой данных, вы не получаете больших накладных расходов, используя отдельные DataContexts.

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

Не существует встроенного метода для периодической отправки, но вы можете наблюдать за количеством элементов в DataContext.GetChangeSet() и отправлять, когда это число превышает заданный порог. Но делать это следует только в том случае, если профилирование показывает, что создание новых DataContexts действительно является узким местом в вашей системе.

1 голос
/ 23 августа 2011

Если у вас есть много объектов, которые содержат довольно мало данных, вы можете начать увеличивать использование памяти.DataContext хранит все отслеженные изменения в памяти, пока вы не вызовете SubmitChanges.Я бы порекомендовал измерить использование памяти вашей программой, чтобы увидеть, будет ли это проблемой для вас.Если проблема с памятью, то да, вам следует вызвать SubmitChanges, чтобы DataContext мог удалить часть этой информации оттуда.

Хотя вызовы SubmitChanges за один вызов имеют свои преимущества и недостатки.Допустим, у вас действительно много данных, и вы используете один вызов SubmitChanges.Это блокирует поток, в котором он находится, до его завершения, а в некоторых случаях это может занять очень и очень много времени.Это плохо, если вы хотите сделать что-то, например, возобновить поток, сообщить о ходе выполнения или выполнить другие побочные действия.В этих случаях вам следует периодически вызывать SubmitChanges, чтобы позволить потоку возобновить обработку другой логики, если она есть или нужна.

Если вам действительно все равно, сколько времени это займет, это ничего не изменитиначе, тогда единственный вызов SubmitChanges хорош.

В любом случае, SubmitChanges по-прежнему разделяет каждое изменение на отдельную команду и выполняет каждую команду по отдельности.Таким образом, он никогда не выполняет групповые или пакетные команды, он всегда один за другим, независимо от того, выполняете ли вы периодические вызовы SubmitChanges или один вызов.

Страница MSDN на этомпоможет вам лучше понять SubmitChanges.Есть и другие полезные ресурсы, разбросанные вокруг.

...