首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BlockingCollection与字典

BlockingCollection与字典
EN

Stack Overflow用户
提问于 2014-12-28 17:12:42
回答 1查看 3.5K关注 0票数 1

我有一个关于使用BlockingCollection和字典编写代码的问题。

我的目标是读取一堆文本文件,并以并行方式处理它们。所处理的数据将存储在BlockingCollection实例中,以便可以将这些处理过的数据写入文件。

我想使用BlockingCollection的原因是.

(1)在GenerateDataFiles()进行CPU密集型工作时,为了节省时间,同时使用者任务可以执行与IO相关的工作,以及

(2)在将所有已处理的数据写入文件之前,将其存储在列表中,以减少内存使用量。

对于(2),如果在将数据写入文件之前存储所有数据,则内存消耗超出我的桌面所能承受的(因为它读取的数据超过30 of ),因此我必须使用这种生产者-消费者方法。

此外,我在BlockingCollection实例(或字典)中插入键值对时遇到了问题。请说明进行数据插入的正确方法。

下面的代码是我解决这个问题的尝试。我可能在这方面犯了一些错误,因为我是BlockingCollection新手。请提出一些修改(和修改代码),以便我可以解决这个问题。

代码语言:javascript
复制
class SampleClass
{
    static void Main(string[] args)
    {            
        SampleClass sampleClass = new SampleClass();
        sampleClass.run();
    }

    private void run()
    {
        Task consumer = Task.Factory.StartNew(() => WriteDataToFiles());
        GenerateDataFiles();
    }

    BlockingCollection<Dictionary<string, List<string>>> bc = new BlockingCollection<Dictionary<string, List<string>>>();

    private void GenerateDataFiles()
    {
        DirectoryInfo directory = new DirectoryInfo(@"D:\Data\");
        FileInfo[] array_FileInfo = directory.GetFiles("*.txt", SearchOption.TopDirectoryOnly);

        Parallel.ForEach(array_FileInfo, fileInfo => 
        {
            string[] array_Lines = File.ReadAllLines(fileInfo.FullName);

            // do some CPU-intensive data parsing and then add the processed data to the blocking collection
            // It has to be inserted in pairs (key = file path, value = list of strings to be written to this file)

        });
    }

    private void WriteDataToFiles()
    {
        foreach (var item in bc.GetConsumingEnumerable())
        {
            foreach (var key in item.Keys)
            {
                File.WriteAllLines(key, item[key]);
            }
        }

    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-28 20:19:11

考虑使用Tuple,而不是在BlockingCollection中使用Dictionary。此外,还需要调用CompleteAdding()以在WriteDataToFiles中结束foreach

代码语言:javascript
复制
BlockingCollection<Tuple<string, List<string>>> bc = new BlockingCollection<Tuple<string, List<string>>>();

private void GenerateDataFiles()
{
    DirectoryInfo directory = new DirectoryInfo(@"D:\Data\");
    FileInfo[] array_FileInfo = directory.GetFiles("*.txt", SearchOption.TopDirectoryOnly);

    Parallel.ForEach(array_FileInfo, fileInfo => 
    {
        string[] array_Lines = File.ReadAllLines(fileInfo.FullName);

        // do some CPU-intensive data parsing and then add the processed data to the blocking collection
        // It has to be inserted in pairs (key = file path, value = list of strings to be written to this file)
        List<string> processedData = new List<string>();  // ... and add content
        bc.Add(new Tuple<string, List<string>>(fileInfo.FullName, processedData));
    });
    bc.CompleteAdding();
}

private void WriteDataToFiles()
{
    foreach (var tuple in bc.GetConsumingEnumerable())
    {
        File.WriteAllLines(tuple.Item1, tuple.Item2);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27678690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档