【发布时间】:2011-05-12 18:43:56
【问题描述】:
当前实现:等到parallelCount 值被收集,使用ThreadPool 处理值,等到所有线程完成,重新收集另一组值等等...
代码:
private static int parallelCount = 5;
private int taskIndex;
private object[] paramObjects;
// Each ThreadPool thread should access only one item of the array,
// release object when done, to be used by another thread
private object[] reusableObjects = new object[parallelCount];
private void MultiThreadedGenerate(object paramObject)
{
paramObjects[taskIndex] = paramObject;
taskIndex++;
if (taskIndex == parallelCount)
{
MultiThreadedGenerate();
// Reset
taskIndex = 0;
}
}
/*
* Called when 'paramObjects' array gets filled
*/
private void MultiThreadedGenerate()
{
int remainingToGenerate = paramObjects.Count;
resetEvent.Reset();
for (int i = 0; i < paramObjects.Count; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object obj)
{
try
{
int currentIndex = (int) obj;
Generate(currentIndex, paramObjects[currentIndex], reusableObjects[currentIndex]);
}
finally
{
if (Interlocked.Decrement(ref remainingToGenerate) == 0)
{
resetEvent.Set();
}
}
}, i);
}
resetEvent.WaitOne();
}
我已经看到这种方法显着提高了性能,但是有许多问题需要考虑:
[1] 可以避免在paramObjects 中收集值并使用resetEvent 进行同步,因为线程(或当前值集与下一组值)之间没有依赖关系。我这样做只是为了管理对reusableObjects 的访问(当一组paramObjects 完成处理时,我知道reusableObjects 中的所有对象都是免费的,所以taskIndex 被重置并且下一组值的每个新任务将有其独特的“reusableObj”可供使用)。
[2] reusableObjects 的大小和ThreadPool 使用的线程数之间没有真正的联系。我可能会将reusableObjects 初始化为有10 个对象,并说由于某些限制,ThreadPool 只能为我的MultiThreadedGenerate() 方法运行3 个线程,那我就是在浪费内存。
那么通过摆脱paramObjects,如何才能以一种方式改进上述代码,即一旦一个线程完成它的工作,该线程返回它使用的taskIndex(或reusableObj)并且没有需要更长的时间,以便它可用于下一个值。此外,代码应该创建一个reUsableObject 并仅在需要时将其添加到某个集合中。在这里使用队列是个好主意吗?
谢谢。
【问题讨论】:
-
您使用的是哪个版本的 .Net?
标签: c# multithreading .net-3.5 queue threadpool