System.Threading.ThreadPool(不包括内核)



我有一台多核体系结构计算机,它正在使用.Net 4.5.2 System.Threading.ThreadPool命名空间执行进程。这些过程是长时间的数学计算。这些进程可能会执行数天甚至数周。我不想创建自己的线程池。使用 System.Threading.ThreadPool 命名空间非常好。但是,在我的多核体系结构计算机上,线程池管理器非常贪婪,并且在所有内核之间进行负载平衡。不幸的是,我在每个核心上的流程也很贪婪。他们想垄断核心并以 100% 的速度执行,直到它完成任务。我对此很好,除了操作系统冻结了。从字面上看,我无法移动鼠标并与桌面交互。我想做的是为操作系统保留一个内核,以便鼠标和 gui 仍然响应。排除内核(及其可用线程)以使操作系统运行似乎是合乎逻辑的。

有谁知道如何使用System.Threading.ThreadPool完成此操作?

****答****

首先,我的问题有问题。这是由于我对这个主题缺乏经验。其次,如果你的谷歌搜索把你带到了这个问题,这意味着你的思维也是错误的;由您的谷歌搜索词证明。但这很好。现在你可以学习正确的方法了。就在这里。

这个问题的简短回答:System.Threading.ThreadPool 无法解决您的问题。

稍微好一点的答案:任务并行库(TPL)是.NET Framework 4.0中System.Threading和System.Threading.Tasks命名空间中的一组公共类型和API。TPL 动态扩展并发程度,以有效地使用所有可用的内核。通过使用 TPL,您可以最大限度地提高代码的性能,同时专注于程序旨在完成的工作。

祝你好运,祝你编码愉快!

@ScottChamberlain:因为数学运算依赖于从外部网络资源中提取值。该资源可能由于我无法控制的原因而被阻止(也许另一个用户正在访问它,阻止直到他们释放它)。– 树液桶

您需要做的是将获取来自网络资源的数据与该资源的处理分开。使用BlockingCollection作为缓冲区,在两个部分之间建立管道。

BlockingCollection<YourData> _collection = new BlockingCollection<YourData>();
public void ProcessInParallel()
{
    //This starts up your workers, it will create the number of cores you have - 1 workers.
    var tasks = new List<Task>();
    for(int i = 0; i < Environment.NumberOfLogicalCores - 1; i++)
    {
        var task = Task.Factory.StartNew(DataProcessorLoop, TaskCreationOptions.LongRunning);
        tasks.Add(task);
    }
    //This function could be done in parallel too, _collection.Add is fine with multiple threads calling it.
    foreach(YourData data in GetYourDataFromTheNetwork())
    {
        //Put data in to the collection, the first worker available will take it.
        _collection.Add(data);
    }
    //Let the consumers know you will not be adding any more data.
    _collection.CompleteAdding();
    //Wait for all of the worker tasks to drain the collection and finish.
    Task.WaitAll(tasks);
}
private void DataProcessorLoop()
{
    //this will pull data from the collection of work to do, when there is no work to do
    //it will block until more work shows up or CompleteAdding is called.
    foreach(YourData data in _collection.GetConsumingEnumerable())
    {
        CrunchData(data)
    }
}

最新更新