我有一个处理两个列表中的字的方法,优先级列表和标准列表。
ConcurrentBag<Word> PriorityWords = ...;
ConcurrentBag<Word> UnprocessedWords = ...;
public void ProcessAllWords()
{
while (true)
{
Word word = SelectWordToProcess();
if (word == null) break;
ProcessWord(word);
}
}
private Word SelectWordToProcess()
{
Word word;
if (PriorityWords.TryTake(out word) || UnprocessedWords.TryTake(out word))
return word;
else
return null;
}
public void ProcessWord(Word word) { ... }
我想在多个核心上运行此方法。目前,我只需为每个处理器打开一个线程:
for (int i = 0; i < Environment.ProcessorCount; i++)
{
new Thread(ProcessAllWords).Start();
}
是否有更合适的方法让系统根据当前系统性能决定打开多少线程,类似于Parallel.ForEach()
?
编辑:有关应用程序的更多详细信息。
单词列表预填充约180,000个单词,每个单词将与其他单词一起排列。 ProcessAllWords
是O(n²)操作。线程将全部运行,直到处理完所有单词,然后终止。当线程正在运行时,我可以通过将它们添加到PriorityWords
列表来异步地为特定单词赋予优先级。初步测试显示我的系统处理大约5字/秒,因此10小时的100%CPU处理。
答案 0 :(得分:1)
启动Environment.ProcessorCount线程的方法很好。任务并行库将执行您正在寻找的自动调度,但代价是过度订阅CPU。这会降低应用程序对优先级单词的响应速度。
对于使用TPL的各种方法,parallel for和task factory都会排队一堆单词,使其对优先级没有反应。您可以使用生成器方法和PLINQ来维护您的优先级,但随后您将获得固定数量的线程。您可以设置线程计数或使用默认值2xEnvironment.ProcessorCount。总而言之,由于您的任务受CPU限制,我会保留您当前的实现。