Дескрипторы, выпускаемые поврежденный так или иначе?

Странная проблема. Возможно, кто-то может дать некоторое понимание.

  • Сценарий 1. У меня есть TBitmap в памяти, которая записана в то, в то время как сложные вычисления происходят для вычисления цвета каждого пикселя. Время от времени (обычно после каждой горизонтальной строки, что битовый массив заполнен) TBitmap оттянут к изображению на форме (image1. Холст. Потяните (0, 0, TBitmap). Большую часть времени это хорошо работает, но я заметил, что, если существует много медленных сложных каиков для каждой растровой строки (говорят, что взятие больше чем 30 secs или минута для вычисления) затем основная форма имеет мгновенное "мерцание", которое так или иначе стирает битовый массив, таким образом image.draw звонят, только проводит последнюю расчетную линию, и первые y строки заменяются пустым местом в битовом массиве. Я обошел это путем блокировки битового массива до вычислений.

  • Сценарий 2. Это - основная стычка. Я пишу в TMemoryStream, а не битовый массив. То же соглашение. Вычисления происходят для вычисления каждого пиксельного значения, и затем каждое пиксельное значение записано в TMemoryStream с memstream. Запишите (bytevalue, 1) во время процесса. В конце всех вычислений я сохраняю поток к битовому массиву с memstream. SaveToFile ('whatever.bmp') и затем освобождают поток с memstream. Свободный. Если вычисление быстро затем, поток сохраняет, какой размер (я делаю тесты с 10000x10000 размеры).

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

Какие-либо идеи? Это действительно сосет. Особенно, когда каждое единственное изображение может занять час для создания только, чтобы найти, что, когда оно заканчивается, что-то в фоновом режиме произошло и повредило битовый массив или TMemoryStream.

Есть ли какой-либо способ, как который я могу заблокировать дескриптор TMemoryStream, я могу с битовым массивом? Это может помочь. Или некоторое объявление для сообщения Delphi "Не смешивает с моими объектами, даже если похоже, что приложение занимает слишком много времени"

Или делает любой знает причину бэкэнда в Delphi, который заставляет это происходить.

TMemoryStream создается в процедуре, которая делает все вычисления так локальный объект. С растровой проблемой битовый массив был глобальной переменной вне процедуры, и это произошло, таким образом, я не думаю, что это - причина.

Это также находится под Windows 7, но я заметил проблему исходного растрового изображения в соответствии с Vista.

Обновление 1:

Извините за не использование комментариев, но существует ограничение на размер текста...

В ответ на Remy (и кто-либо еще читающий это)...

Единственный распараллелил. Для memorystream это хорошо работает для 5000x5000 разрешение, если вычисления быстры, но сбои, если вызовы являются медленными.

Как основная платформа код вроде

SetupMemorystream; 
for y:=0 to height do 
   for x:=0 to width do 
      DoCalcs;
      SetByteValue; 
   end; 
end; 
SaveStream; 

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

Это было идентично с использованием в памяти TBitmap, пока я не обнаружил, что мог заблокировать битовый массив, который останавливает Delphi и/или Windows, перераспределяющий новый дескриптор к нему, "когда это хочет к", который повреждает данные в битовом массиве.

Это - слишком много совпадения, чтобы не думать, что той же проблемы не происходит с TMemoryStream и его дескриптором.

Обновление 2:

Еще один, возможно, полезный бит информации.

Когда TMemoryStream сохраняет OK, получающийся файл (для 5000x5000 битовый массив) составляет 75 000 054 байта в размере.

Когда сохраненный поток поврежден, это, кажется, случайное значение (размера от того, когда дескриптор был поврежден, пока поток не сохраняется). Размеры в качестве примера составили 22 МБ и 9 МБ.

То, когда я смотрю на получающиеся файлы, является Hex-редактором, он показывает, что запуск файлов корректен с блоками заголовка, но заключительные части становятся усеченными так или иначе.

Это настолько причудливо. Так или иначе я могу абсолютно наверняка сбросить TMemoryStream после вызова SaveToFile и прежде, чем освободить его?

5
задан Jim McKeeth 15 December 2009 в 06:05
поделиться

5 ответов

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

  2. Думаю, вам нужно вычесть 1 из значений высоты и ширины в цикле for

Ура

1
ответ дан 15 December 2019 в 06:28
поделиться

Спасибо за все подсказки, ребята. Циклы имели правильный код от 0 до ширины-1.

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

Я должен был знать, что это моя ошибка, а не проблема Delphi.

1
ответ дан 15 December 2019 в 06:28
поделиться

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

Я недавно столкнулся с этим: это в QC 80148. Однако вы мало что можете с этим поделать. это, потому что функция Windows CloseHandle также вряд ли вернет какую-либо ошибку.

1
ответ дан 15 December 2019 в 06:28
поделиться

Трудно найти такую ​​ошибку, просто предполагая, что происходит. Поскольку операция настолько длинная, просто повторять и ждать, если будет обнаружена ошибка, стоит дорого.

Я предлагаю вам регистрировать каждый шаг процесса. Вероятно, вы получите огромный журнал, но он покажет вам, где что-то пошло не так. Повторите процесс и улучшите свой журнал,

0
ответ дан 15 December 2019 в 06:28
поделиться

Вы можете использовать вызов API FlushFileBuffers (filestream.Handle) , чтобы сбросить tFileStream, но я предполагаю, что что-то еще происходит, чтобы вызвать повреждение в первую очередь, который может быть таким же простым, как переход вашего цикла от 0 к ширине, а не от 1 к ширине или от 0 к ширине-1 ... трудно сказать, не анализируя, что ваши подпрограммы делают для заполнения вашего потока памяти.

0
ответ дан 15 December 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: