当前实现:等到parallelCount
收集值,使用ThreadPool
处理值,等待所有线程完成,重新收集另一组值,等等......C# - 将数据从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
完成处理时,我知道可重用对象中的所有对象都是空闲的,所以taskIndex
被重置,并且下一组值的每个新任务都将具有其唯一的'可重用对象' 跟...共事)。
[2]在reusableObjects
的大小和ThreadPool
使用的线程数之间没有真正的连接。我可能初始化reusableObjects
有10个对象,并说由于一些限制,ThreadPool只能为我的MultiThreadedGenerate()
方法运行3个线程,然后我浪费内存。
因此,通过摆脱paramObjects
,怎么能在上面的代码中,一旦一个线程完成了工作的方式加以完善,该线程返回其taskIndex
(或reusableObj
)它使用和不再需要,使其可用于下一个值。此外,代码应该创建一个reUsableObject
并将其添加到一些收集只有当有需求时。在这里使用Queue是一个好主意吗?
谢谢。
你在什么版本的.Net上? – 2010-11-19 17:53:01
我使用.NET 3.5 – alhazen 2010-11-19 17:54:38