views:

92

answers:

2

I'm currently working in a dispatcher service that processes thousands of messages delivered in different channels (email, private message, application message) using EF4 and WCF.

To try to speed up message dispatching i'm trying to use Parallels:

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

My Dispatch method uses reflection to match channel configuration method and process each message concurrently, but I'm having big problems trying to update EF objects within the threads when i make SaveChanges() to a global entity (it's initialized on application_start)

Problems come in various flavors:

  • Null object references
  • List item The property is part of the object's key information and cannot be modified.
  • The underlying provider failed on Open.
  • New transaction is not allowed because there are other threads running in the session. (after forcing connection open if closed)

The question is if EF4 is thread safe to implement this scenario? Is my approach of having a global Entities the best solution, or should i make per task EF4 initializations?

Any help is welcome, has i already lost 2 hours trying to figure out a possible workaround.

A: 

Using shared context for concurrent WCF calls is really bad practice. You should always use new context for each call. I explained the reason here.

Ladislav Mrnka
A: 

I don't have a great answer for you but when faced with a simmilar problem I ended up adding all my changes to a static common System.Collections.Concurrent.ConcurrentBag and then commiting them after all threads/tasks were finished.

It is a compromise, but may be a "good enough" solution.

Dimestore Cowboy