views:

121

answers:

2

I have multiple processor objects which I use with ThreadPool to use them in a paralel process. Which processor I am going to use is basically depend on the incoming data and there might be more than 2000 different types; so as soon as my app runs it creates 1-2K number of processors in a dictionary and run the one I need according to incoming data in ThreadPool. Any process does not take more than a millisecond btw.

My psuedo code for running in the ThreadPool is below:

public void onIncomingNewData(rawData)
{
     if (!ThreadPool.QueueUserWorkItem(processors[rawData.Type.Id].Process, rawData))
     {
         Console.WriteLine("Work item cannot be queued!");
      }

      //Thread.Sleep(1);
}

My problem here is synchrnozing the Processer objects; they have their internal cache and I dont want multiple threads running the same Process objects process method.

At the moment I am using "lock" inside of the process method and some other private methods that process method calls. But what would be the best approach to do this?

+1  A: 

What you basically need is a processor pool based on type. Instead of caching an actual processor in the processors dictionary, create a pool class that keeps track of available and active processors. When a request comes in, find the appropriate pool. Then see if there are any available processors. If so, take it out of the available list and put it in the active list. Run the Process method, then take it back out of the active list and put it into the available list.

You can get away with not using active/available lists and just using an active flag instead. Depending on number of concurrent processes, this might be more efficient.

However, if each Process call only takes a millisecond, then this sounds like overkill for your particular needs. I would recommend using lock() for synchronization and add some logging to see how often processes wait on locks. If in testing you find it to be a problem, then go ahead with something more complex.

You also probably need locking around accesses to processors dictionary unless it is threadsafe already. If the dictionary is 100% preloaded, it might not be necessary.

Sam
Agreed - this sounds a lot like a problem Reed Copsey blogged about recently (at http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via-threadlocalt/). His answer was to use instance-level thread-local storage available in .NET 4.0. If you aren't using 4.0 yet, a pool is probably the best solution. As Reed discovered, locking the shared process data can undo the performance gains you get by parallelizing, especially for such fast operations.
Jeff Sternal
A: 

Instead of injecting a processor method into the thread pool, instead have each processor maintain its own queue of requests and inject its own worker method into the thread pool.

ebpower