C#-将数据从线程池线程传回主线程
当前实现:等待收集C#-将数据从线程池线程传回主线程,c#,multithreading,.net-3.5,queue,threadpool,C#,Multithreading,.net 3.5,Queue,Threadpool,当前实现:等待收集parallelCount值,使用ThreadPool处理值,等待所有线程完成,重新收集另一组值,依此类推 代码: private static int parallelCount=5; 私有索引; 私有对象[]参数对象; //每个线程池线程应仅访问阵列的一项, //完成后释放对象,供另一个线程使用 私有对象[]可重用对象=新对象[parallelCount]; 私有void多线程生成(对象paramObject) { paramObjects[taskIndex]=param
parallelCount
值,使用ThreadPool
处理值,等待所有线程完成,重新收集另一组值,依此类推
代码:
private static int parallelCount=5;
私有索引;
私有对象[]参数对象;
//每个线程池线程应仅访问阵列的一项,
//完成后释放对象,供另一个线程使用
私有对象[]可重用对象=新对象[parallelCount];
私有void多线程生成(对象paramObject)
{
paramObjects[taskIndex]=paramObject;
taskIndex++;
if(taskIndex==parallelCount)
{
多线程生成();
//重置
任务索引=0;
}
}
/*
*当“paramObjects”数组被填充时调用
*/
私有void多线程生成()
{
int remainingToGenerate=paramObjects.Count;
resetEvent.Reset();
for(int i=0;i
我已经看到了这种方法的显著性能改进,但是有许多问题需要考虑:
[1] 可以避免在paramObjects
中收集值以及使用resetEvent
进行同步,因为线程之间(或当前值集与下一组值之间)没有依赖关系。我这样做只是为了管理对reusableObjects
的访问(当一组paramObjects
完成处理时,我知道reusableObjects中的所有对象都是自由的,因此taskIndex
被重置,下一组值的每个新任务都将有其唯一的“reusableObj”可使用)
[2] reusableObjects
的大小与ThreadPool
使用的线程数之间没有真正的联系。我可能会将reusableObjects
初始化为有10个对象,并说由于一些限制,ThreadPool只能为我的multi-threadedGenerate()
方法运行3个线程,这样我就浪费了内存
因此,通过去除paramObjects
,如何改进上述代码,使一个线程完成其任务后,该线程返回其使用的taskIndex
(或reusableObj
),而不再需要它,以便下一个值可以使用它。此外,代码应该创建一个reUsableObject
,并仅在有需求时将其添加到某个集合中。在这里排队是个好主意吗
谢谢。真的没有理由再做自己的手动线程和任务管理了。您可以使用(并且可能用于结果排序)将其重新构造为更松散耦合的模型 如果您不需要等待全部工作完成后再将每个
任务
交付处理,则性能可以进一步提高
TPL是在.NET4.0中出现的,但现在已经过时了。下载。真的没有理由再做你自己的手动线程和任务管理了。您可以使用(并且可能用于结果排序)将其重新构造为更松散耦合的模型 如果您不需要等待全部工作完成后再将每个
任务
交付处理,则性能可以进一步提高
TPL是在.NET4.0中出现的,但现在已经过时了。下载。您使用的是什么版本的.Net?您使用的是什么版本的.Net?+1我不知道后端端口,所以谢谢您提供的信息。@Brian-我看到了此引用,但以前没有跟踪到它,如果隐藏得很好,它会非常有用。+1我不知道后端端口,所以,谢谢你提供的信息。@Brian-我已经看到了这篇文章的参考文献,但之前没有找到它,如果隐藏得好的话,它会非常有用。
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();
}