0

В настоящее время я работаю в диспетчерской службе, которая обрабатывает тысячи сообщений, отправляемых по разным каналам (электронная почта, личное сообщение, сообщение приложения) с использованием EF4 и WCF.Совпадает с объектами EF4 (Parallel + EF4)

Чтобы попытаться ускорить сообщение диспетчерская я пытаюсь использовать Parallels:

Parallel.ForEach(currentMessageList, m => 
{ 
Processors.DispatcherWrapper.Dispatch(m, m.unfChannels.AgentName, m.unfChannels.AgentParameters); 
} 
); 

Мой метод отправки использует отражение, чтобы соответствовать метод настройки канала и обработки каждого сообщения одновременно, но у меня возникают большие проблемы при попытке обновить объекты EF в резьбе, когда я делаю SaveChanges() для глобального объекта (он инициализируется на Application_Start)

Проблемы бывают различных вкусов:

  • Ссылки на нулевые объекты
  • Элемент списка Свойство является частью ключевой информации объекта и не может быть изменено.
  • Исходный провайдер не смог открыть Open.
  • Новая транзакция не допускается, так как в сеансе есть другие потоки. (после того, как принудительное соединение разомкнуто, если оно закрыто)

Вопрос в том, является ли EF4 безопасным потоком для реализации этого сценария? Является ли мой подход наличием глобальных сущностей лучшим решением, или я должен выполнить инициализацию EF4 для каждой задачи?

Любая помощь приветствуется, я уже потерял 2 часа, пытаясь выяснить возможное обходное решение.

+0

Tried do инициализирует новое Entitie и получает: EdmType не может быть сопоставлен классам CLR несколько раз. EdmType '' отображается более одного раза. – hmf

+1

ObjectContext не является потокобезопасным. http://stackoverflow.com/questions/3258357/good-advices-to-use-ef-in-a-multithread-program –

ответ

2

Использование общего контекста для одновременных вызовов WCF - действительно плохая практика. Вы всегда должны использовать новый контекст для каждого вызова. Я объяснил причину here.

1

У меня нет отличного ответа для вас, но когда вы столкнулись с близкой проблемой, я в итоге добавил все мои изменения в статический общий System.Collections.Concurrent.ConcurrentBag, а затем отправил их после завершения всех потоков/задач ,

Это компромисс, но может быть «достаточно хорошим» решением.

Смежные вопросы