У меня вопрос о написании кодов с использованием BlockingCollection и Dictionary.BlockingCollection и словарь
Моя цель - прочитать кучу текстовых файлов и обработать их параллельно. Обработанные данные будут храниться в экземпляре BlockingCollection, чтобы эти обработанные данные могли быть записаны в файл.
Причины, почему я хочу использовать BlockingCollection это ...
(1), чтобы сэкономить время, пока GenerateDataFiles() делает процессор интенсивной работы и потребительские задачи могут сделать IO соответствующей работу в то же время , и
(2) уменьшить использование памяти по сравнению с случаем, когда я храню все обработанные данные в списке перед записью любого из них в файл.
Для (2), если я храню все данные перед их записью в файл, потребление памяти больше, чем мой рабочий стол может позволить себе (поскольку он читает более 30 ГБ данных), и поэтому я должен использовать этого производителя - потребительский подход.
Также у меня возникла проблема при вставке пары ключ-значение в экземпляр 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]);
}
}
}
}
Сторона примечания. Запись нескольких экземпляров IO приведет к ухудшению производительности приложений, особенно при использовании механического HD. Кроме того, я не вижу, как вы вставляете какие-либо данные в «BlockCollection». –
@YuvalItzchakov. Причина, по которой я не включал коды для вставки данных в BlockingCollection, заключается в том, что синтаксис, который я написал в VS, показывает ошибку. Вот почему я оставил его пустым, вместо того чтобы писать что-то, чтобы запутать других. – Roy
Запуск кода в 'Parallel.ForEach' будет по-прежнему зависеть от вашего процесса, потому что, поскольку вы используете' File.ReadAllLines', и вы не ставите очередь на любой элемент из коллекции. –