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();    
}