【问题标题】:C# - Pass data back from ThreadPool thread to main threadC# - 将数据从 ThreadPool 线程传回主线程
【发布时间】: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


【解决方案1】:

真的没有理由再进行自己的手动线程和任务管理了。您可以使用Task Parallel Library 将其重构为更松散耦合的模型(可能还有System.Collections.Concurrent 用于结果整理)。

如果您无需等待完成所有工作后再将每个 Task 交给处理,则性能可以进一步提高。

TPL 在 .Net 4.0 中出现,但当时是 back-ported to .Net 3.5。下载here。

【讨论】:

  • +1 我不知道后端端口,所以感谢您提供的信息。
  • @Brian - 我已经看到了对此的参考,但之前没有追踪到它,如果隐藏得很好,它会非常有用。
猜你喜欢
  • 2012-05-07
  • 1970-01-01
  • 2018-01-30
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多