我有一个帖子,称之为“解析线程”。
Thread parsingThread = new Thread(myMethod);
我在这个线程上执行一些计算,其中最后一个涉及更多的并行计算。
public void ReadCityFiles(BlockingCollection<GeonamesFileInfo> files)
{
Parallel.ForEach<GeonamesFileInfo>(
files.GetConsumingPartitioner<GeonamesFileInfo>(),
new ParallelOptions { MaxDegreeOfParallelism = _maxParallelism },
(inputFile, args) =>
{
RaiseFileParsing(inputFile);
using (var input = new System.IO.StreamReader(inputFile.FullName))
{
while (!input.EndOfStream)
{
RaiseEntryParsed(ParseCity(input.ReadLine()));
Interlocked.Increment(ref _parsedEntries);
}
}
RaiseFileParsed(inputFile);
});
RaiseDirectoryParsed(Directory);
}
问题在于,当这些非常长且计算量很大的异步foreach操作完成(约30分钟)时,“解析线程”不会恢复。我的GUI仍然是响应式的,但是永远不会调用应该继续在“解析线程”上运行的RaiseDirectoryParsed函数。到目前为止,我调试了程序,对于在这种情况下该怎么做,我感到非常困惑。
答案 0 :(得分:2)
BlockingCollection
的要点是,当一个操作现在无法执行,但可能在将来(例如Take()
或Add()
对有限容量的集合)时,它将会块。这同样适用于GetConsumingEnumerable()
,因此也适用于GetConsumingPartitioner()
:如果集合当前为空,则枚举将阻塞,直到您向集合中添加更多项目。
但是还有一种方法可以告诉集合你不再添加新项目,并且从现在起它不应该阻塞:the CompleteAdding()
method。如果您在知道不再向集合中添加新项目时调用此项,则Parallel.ForEach()
将不再阻止,您的线程将继续执行。