2010-02-05 67 views
1

我有多个处理器对象,我使用ThreadPool在并行进程中使用它们。我要使用哪个处理器基本上取决于传入的数据,并且可能有超过2000种不同的类型;所以只要我的应用程序运行,它会在字典中创建1-2K个处理器,并根据ThreadPool中的传入数据运行我需要的处理器。任何进程不会超过一毫秒btw。使用ThreadPool进行对象同步

我在线程池运行的伪代码如下:

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

     //Thread.Sleep(1); 
} 

我的问题这里synchrnozing之处理对象;他们有他们的内部缓存,我不希望多个线程运行相同的过程对象处理方法。

此刻,我正在使用“锁定”进程方法和一些其他处理方法调用的私有方法。但是,最好的方法是什么?

+0

取决于你的意思是“同步”。这种同步的目标是什么? – Will 2010-02-05 15:02:29

回答

1

你基本上需要的是一个基于类型的处理器池。不是在处理器字典中缓存实际处理器,而是创建一个跟踪可用和活动处理器的池类。当请求进入时,找到合适的池。然后看看是否有任何可用的处理器。如果是,请将其从可用列表中取出并放入活动列表中。运行Process方法,然后将其从活动列表中取出并放入可用列表中。

你可以逃避不使用活动/可用列表,而只是使用活动标志。根据并发进程的数量,这可能更有效。

但是,如果每个进程调用只需要一毫秒,那么这听起来像是针对您的特定需求的矫枉过正。我建议使用lock()进行同步,并添加一些日志记录来查看进程等待锁定的频率。如果在测试中发现它是一个问题,那么继续处理更复杂的问题。

您也可能需要锁定对processors字典的访问,除非它已经是线程安全的。如果字典是100%预加载的,则可能不需要。

+0

同意 - 这听起来很像一个问题里德科普塞最近博客(在http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via -threadlocalt /)。他的回答是使用.NET 4.0中提供的实例级线程本地存储。如果你还没有使用4.0,一个池可能是最好的解决方案。正如Reed发现的,锁定共享进程数据可以消除并行化所带来的性能收益,特别是对于这种快速操作。 – 2010-02-05 15:12:46

0

取而代之的是向线程池中注入处理器方法,而不是让每个处理器维护自己的请求队列,并将自己的工作者方法注入到线程池中。