C# Threading — чтение и хеширование нескольких файлов одновременно, самый простой способ?

Я пытался получить то, что я считаю простейшей формой потоковой передачи для работы в моем приложении, но я просто могу не делай этого.

Что я хочу сделать: у меня есть основная форма со полосой состояния и индикатором выполнения. Мне нужно прочитать что-то между 3 и 99 файлами и добавить их хэши в строку [], которую я хочу добавить в список всех файлов с соответствующими хэшами.После этого я должен сравнить элементы в этом списке с базой данных (которая поставляется в виде текстовых файлов). Как только все это будет сделано, мне нужно обновить текстовое поле в основной форме и индикатор выполнения до 33%; в основном я просто не хочу, чтобы основная форма зависала во время обработки.

Файлы, с которыми я работаю, всегда в сумме составляют 1,2 ГБ (+/- несколько МБ), что означает, что я должен иметь возможность читать их в byte[] и обрабатывать оттуда (мне нужно вычислить CRC32, MD5 и SHA1 каждого из этих файлов, так что это должно быть быстрее, чем чтение их всех с жесткого диска в 3 раза).

Также я должен отметить, что некоторые файлы могут иметь размер 1 МБ, а другие — 1 ГБ. Первоначально я хотел создать 99 потоков для 99 файлов, но это кажется неразумным, я полагаю, что было бы лучше повторно использовать потоки небольших файлов, в то время как более крупные файловые потоки все еще работают. Но это звучит довольно сложно для меня, поэтому я не уверен, что это разумно.

До сих пор я пробовал workerThreads и backgroundWorkers, но, похоже, ни один из них не работает слишком хорошо для меня; по крайней мере, backgroundWorkers работали НЕКОТОРОЕ время, но я даже не могу понять, почему они не будут работать в другое время... в любом случае основная форма все еще зависала. Теперь я прочитал о библиотеке параллельных задач в .NET 4.0, но я подумал, что лучше спросить кого-то, кто знает, что он делает, прежде чем тратить на это больше времени.

То, что я хочу сделать, выглядит примерно так (без потоковой передачи):

List<string[]> fileSpecifics = new List<string[]>();

int fileMaxNumber = 42; // something between 3 and 99, depending on file set

for (int i = 1; i <= fileMaxNumber; i++)
{
    string fileName = "C:\\path\\to\\file" + i.ToString("D2") + ".ext"; // file01.ext - file99.ext
    string fileSize = new FileInfo(fileName).Length.ToString();
    byte[] file = File.ReadAllBytes(fileName);
    // hash calculations (using SHA1CryptoServiceProvider() etc., no problems with that so I'll spare you that, return strings)
    file = null; // I didn't yet check if this made any actual difference but I figured it couldn't hurt
    fileSpecifics.Add(new string[] { fileName, fileSize, fileCRC, fileMD5, fileSHA1 });
}

// look for files in text database mentioned above, i.e. first check for "file bundles" with the same amount of files I have here; then compare file sizes, then hashes
// again, no problems with that so I'll spare you that; the database text files are pretty small so parsing them doesn't need to be done in an extra thread.

Кто-нибудь будет достаточно любезен, чтобы указать мне правильное направление? Я ищу самый простой способ быстро прочитать и хешировать эти файлы (я считаю, что хеширование занимает некоторое время, в течение которого другие файлы уже могут быть прочитаны) и сохранить вывод в строку [], без зависания основной формы, не более того , не меньше.

Буду благодарен за любую информацию.

РЕДАКТИРОВАТЬ, чтобы уточнить: под «фоновыми работниками, работающими некоторое время» я имел в виду, что (для одного и того же набора файлов), возможно, первое и четвертое выполнение моего кода дает правильный вывод, и пользовательский интерфейс размораживается в течение 5 секунд, для второго, третьего и пятого выполнения он замораживает форму (и через 60 секунд я получаю сообщение об ошибке, в котором говорится, что какой-то поток не ответил в течение этого времени), и я должен остановить выполнение через VS.

Спасибо за все ваши предложения и подсказки, как вы все правильно догадались, я совершенно новичок в многопоточности, и мне придется прочитать отличные ссылки, которые вы, ребята, разместили. Затем я попробую эти методы и отмечу ответ, который помог мне больше всего. Еще раз спасибо!

12
задан Leniel Maccaferri 26 October 2012 в 14:40
поделиться