多线程会话后线程不会恢复

时间:2012-09-02 09:18:50

标签: c# multithreading parallel.foreach

我有一个帖子,称之为“解析线程”。

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函数。到目前为止,我调试了程序,对于在这种情况下该怎么做,我感到非常困惑。

1 个答案:

答案 0 :(得分:2)

BlockingCollection的要点是,当一个操作现在无法执行,但可能在将来(例如Take()Add()对有限容量的集合)时,它将会块。这同样适用于GetConsumingEnumerable(),因此也适用于GetConsumingPartitioner():如果集合当前为空,则枚举将阻塞,直到您向集合中添加更多项目。

但是还有一种方法可以告诉集合你不再添加新项目,并且从现在起它不应该阻塞:the CompleteAdding() method。如果您在知道不再向集合中添加新项目时调用此项,则Parallel.ForEach()将不再阻止,您的线程将继续执行。