我有一个关于使用BlockingCollection和字典编写代码的问题。
我的目标是读取一堆文本文件,并以并行方式处理它们。所处理的数据将存储在BlockingCollection实例中,以便可以将这些处理过的数据写入文件。
我想使用BlockingCollection的原因是.
(1)在GenerateDataFiles()进行CPU密集型工作时,为了节省时间,同时使用者任务可以执行与IO相关的工作,以及
(2)在将所有已处理的数据写入文件之前,将其存储在列表中,以减少内存使用量。
对于(2),如果在将数据写入文件之前存储所有数据,则内存消耗超出我的桌面所能承受的(因为它读取的数据超过30 of ),因此我必须使用这种生产者-消费者方法。
此外,我在BlockingCollection实例(或字典)中插入键值对时遇到了问题。请说明进行数据插入的正确方法。
下面的代码是我解决这个问题的尝试。我可能在这方面犯了一些错误,因为我是BlockingCollection新手。请提出一些修改(和修改代码),以便我可以解决这个问题。
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]);
}
}
}
}发布于 2014-12-28 20:19:11
考虑使用Tuple,而不是在BlockingCollection中使用Dictionary。此外,还需要调用CompleteAdding()以在WriteDataToFiles中结束foreach。
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);
}
}https://stackoverflow.com/questions/27678690
复制相似问题