C # Process Двоичный файл, многопоточная обработка - PullRequest
2 голосов
/ 21 апреля 2010

У меня есть следующий код, который обрабатывает двоичный файл. Я хочу разделить рабочую нагрузку, используя потоки и назначая каждую строку двоичного файла потокам в ThreadPool. Время обработки каждой строки невелико, но при работе с файлами, которые могут содержать сотни строк, имеет смысл разделить рабочую нагрузку.

Мой вопрос касается BinaryReader и безопасности потоков. Прежде всего, то, что я делаю ниже допустимого. У меня есть ощущение, что было бы лучше передать только двоичный файл для каждой строки в метод PROCESS_Binary_Return_lineData.

Обратите внимание, что приведенный ниже код является концептуальным. Я ищу небольшое руководство по этому вопросу, так как мои знания о многопоточности находятся в зачаточном состоянии. Возможно, есть лучший способ достичь того же результата, то есть разделить обработку каждой двоичной строки.

        var dic = new Dictionary<DateTime, Data>();        
        var resetEvent = new ManualResetEvent(false);

        using (var b = new BinaryReader(File.Open(Constants.dataFile, 
                            FileMode.Open, FileAccess.Read, FileShare.Read)))
        {
        var lByte = b.BaseStream.Length;
        var toProcess = 0;

        while (lByte >= DATALENGTH)
        {
            b.BaseStream.Position = lByte;
            lByte = lByte - AB_DATALENGTH;

            ThreadPool.QueueUserWorkItem(delegate
            {
                Interlocked.Increment(ref toProcess);
                var lineData = PROCESS_Binary_Return_lineData(b);

                lock(dic)
                {
                    if (!dic.ContainsKey(lineData.DateTime))
                    {
                     dic.Add(lineData.DateTime, lineData); 
                    }
                }

                if (Interlocked.Decrement(ref toProcess) == 0) resetEvent.Set();
            }, null);
        }
        }

        resetEvent.WaitOne();

Ответы [ 3 ]

3 голосов
/ 21 апреля 2010

Это не выглядит поточно-ориентированным для меня. Если у вас в очереди более одного рабочего элемента, и два из них работают одновременно, позиция читателя может легко измениться между назначением и чтением.

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

2 голосов
/ 21 апреля 2010

Очень редко имеет смысл использовать потоки для улучшения производительности обработки файлов. Поток при запуске на многоядерном процессоре обеспечивает больше циклов процессора. Это редко тот ресурс, который вам не хватает при обработке файлов. Вам нужно больше дисков. Не вариант, конечно.

Тест дыма это первый. Перезагрузите компьютер, чтобы файл не был сохранен в кеше файловой системы. Запустите вашу однопоточную программу и наблюдайте за загрузкой процессора. Taskmgr.exe, вкладка Performance хороша для этого. Если вы не видите максимальный израсходованный процессор при загрузке 100%, то добавление еще одного процессора не ускорит вашу программу.

0 голосов
/ 21 апреля 2010

"У меня такое чувство, что было бы лучше пропустить только двоичный файл для каждой строки в PROCESS_Binary_Return_lineData метод. "

да, вам нужно это сделать, поскольку ваш делегат может не вернуться к чтению из BinaryReader, пока он не будет перемещен

...