Периодически обновлять сущности из нескольких потоков в EF - PullRequest
5 голосов
/ 31 марта 2011

У меня есть следующий сценарий:

У меня есть база данных, в которой хранятся задания, которые отслеживаются и обрабатываются сервером. Доступ к базе данных осуществляется через Entity Framework.

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

Теперь моя проблема в том, что у моих сущностей есть свойство Progress, которое должно обновляться рабочими потоками и периодически записываться в базу данных.

Рабочие потоки обновляют свойство довольно часто (много раз в секунду), но для моих требований достаточно, если база данных обновляется каждые несколько секунд, и я не хочу вносить много ненужных обновлений в базу данных.

Пока что мое решение состоит в том, чтобы рабочие потоки записывали прогресс непосредственно в Entity и чтобы поток, который проверяет наличие обновлений, также выдавал эти изменения в базу данных.

Мой вопрос: безопасен ли этот поток с точки зрения EF? Могу ли я обновить свойства сущности из одного потока и записать изменения в базу данных в другом потоке? Нужен ли какой-либо случай блокировки? Имейте в виду, что я использую DataContext только в одном потоке (добавьте наименее явно, поскольку я не знаю, что делает EF внутри, когда обновляю сущность (не POCO).

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

У вас есть какой-нибудь совет, как это правильно структурировать?

Поскольку каждый работник обновляет статус только для одного Job-Entity, одной из идей было представить прогресс как свойство в классе worker-threads, который выбирается основным потоком, который затем обновляет сущности и выдает обновление в базу данных. Но мне все еще нужен исходный объект Job-Entity в рабочем потоке для чтения данных конфигурации, и если я снова присоединю его к DataContext рабочего потока, я больше не смогу использовать Entity в основном потоке. Я хочу избегать загрузки одного и того же объекта 2 раза, если в этом нет особой необходимости ...

Можно ли автоматически дублировать сущность, чтобы использовать ее в 2 отдельных DataContexts?

Спасибо за любые идеи!

Ответы [ 2 ]

1 голос
/ 03 апреля 2011

В конце я принял следующее решение:

Мой основной класс / основной поток читает задания из базы данных и распределяет их по различным рабочим потокам. Для каждого задания существует соответствующий Job-Executor, чей метод .Execute () запускается рабочим потоком.

По соглашению, классы Executor читают все необходимые данные конфигурации из Job-Entity, когда он создан, и ему больше не разрешается прикасаться к нему в течение периода выполнения. Поскольку построение класса Executor выполняется из основного потока, здесь нет многопоточного доступа.

Изменение состояния, например, выполнение задания, отображается через свойства класса executor и периодически синхронизируется с сущностями / базой данных из основного потока.

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

Весь другой многопоточный доступ к DataContext синхронизируется с блокировками.

0 голосов
/ 31 марта 2011

Я думаю, что вам следует немного переработать свою систему.

Вы столкнулись с проблемой, потому что прогресс сущности хранится внутри сущности.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...