2

私はスレッドを持っています、それを「解析スレッド」と呼びます。

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関数が呼び出されることはありません。私はこの時点までプログラムをデバッグしましたが、この状況で何をすべきかについてかなり困惑しています。

4

1 に答える 1

2

ポイントはBlockingCollection、現在操作を実行できないが、将来実行される可能性がある場合(たとえばTake()Add()容量が制限されているコレクションで)、ブロックされるということです。同じことが当てはまります。GetConsumingEnumerable()したがってGetConsumingPartitioner()、コレクションが現在空の場合、コレクションにアイテムを追加するまで列挙可能オブジェクトはブロックされます。

ただし、新しいアイテムを追加しないこと、および今後空になったときにブロックしないようにすることをコレクションに通知する方法もありますCompleteAdding()メソッドです。コレクションにこれ以上新しいアイテムを追加しないことがわかっているときにこれを呼び出すと、Parallel.ForEach()ブロックされなくなり、スレッドは実行を継続します。

于 2012-09-02T10:47:48.847 に答える