Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Поток+dll

4.5K
07 марта 2007 года
StranikS
44 / / 03.02.2005
Здравствуйте! Проблема с потоками и ресурсами.
Попытаюсь объяснить:

В приложении создан поток скажем Thread1:TThread, который делает следующее:
1. Кэширует БД с помощью RxMemoryData (RxMemoryData НЕ создается дин. в потоке);
2. Используя кэшированные данные, загружает соответствующие битмапы из dll
и отображает их в соотвествующих местах на большом битмапе, скажем BIGBM:BITMAP
(BIGBM - локальная переменная потока; загрузка из dll осуществляется через
TResourceStream (для избежания проблем с палитрой) через лок. переменную скажем
BM:BITMAP; перенос BM на BIGBM осущ. разными способами как методом Draw, так и по
пиксельно через Pixels);
3. Сохраняет BIGBM в файл ".bmp".

Поток запускается скажем по кнопке.
Мной ОТДЕЛЬНО проверен каждый из перечисленных этапов:
1. Данные успешно кэширются;
2. Картинки в BM загружаются. Проверяемая BM успешно перерисовывается на BIGBM;
3. BIGBM успешно сохр. в файл.

НО! В сумме при эксплуатации появляется непонятное явление - при очередном запуске на конечной картинке в файле обязательно какая-нибудь часть (или несколько частей) нарисована частично, как бы недорисована.

Подскажите, пжл., в каком направлении копать (бьюсь уже несколько дней, многое перепробовал).
PS: Когда тоже самое было реализовано не в потоке и без кэширования, то такой проблемы не было.
261
08 марта 2007 года
ahilles
1.5K / / 03.11.2005
наверно, проблемы с синхронизацией, заключи весь код который работает с "контролами" в отдельную процедуру и вызывай её так Synchronize(<твоя процедура>), короче посмотри справку по классу TThread
4.5K
08 марта 2007 года
StranikS
44 / / 03.02.2005
Я постарался исключить варианты такого рода и сделал УПРОЩЕННОЕ тестовое приложение.

Модуль потока:

Код:
unit Thread_ImageCreate;

interface

uses
  Windows, Classes, Forms, Graphics;

type
  TImageCreateThread = class(TThread) //Новый класс
  private

  protected
    procedure ShowError;
    procedure Execute; override;
  public
    constructor Create(CreateSuspennded:Boolean);
  end;

implementation

constructor TImageCreateThread.Create(CreateSuspennded:Boolean);
begin
 inherited Create(CreateSuspennded);
end;

procedure TImageCreateThread.ShowError;
begin
Application.MessageBox(PChar('11111'),'Error',MB_ICONERROR);
end;

procedure TImageCreateThread.Execute;
var ZBitmap,BM:TBitmap;
    i:Integer;
begin
try
ZBitmap:=TBitmap.Create;
ZBitmap.PixelFormat:=pf4bit;
ZBitmap.Width:=4000;
ZBitmap.Height:=4000;

for i:=1 to 1000 do
begin
BM:=TBitmap.Create;
BM.LoadFromFile('c:\1.bmp');
ZBitmap.Canvas.Draw(i*3,i*3,BM);
BM.Free;
end;

ZBitmap.SaveToFile('c:\3.bmp');
ZBitmap.Free;
except
 Synchronize(ShowError);
 end;
end;

end.


Вызов потока из приложения:

Код:
procedure TForm.FormClick(Sender: TObject);
 function GetHandle(iThread:TThread):HWND;
 begin
 if iThread<>nil then Result:=iThread.Handle
 else Result:=HWND(0);
 end;
begin
 if WaitForSingleObject(GetHandle(ImageCreateThread),0)<>WAIT_TIMEOUT then
  begin//запуск потока
  ImageCreateThread:=TImageCreateThread.Create(True);
  ImageCreateThread.FreeOnTerminate:=True;
  ImageCreateThread.Resume;
  end;
end;


Если позапускать поток, то можно увидеть, что в файле 3.bmp часть картинок отсутствует в ряду (случайным образом) - их просто нет. Особо это заметно, если при работе потока интенсивно лазить по интефейсу программы.
261
09 марта 2007 года
ahilles
1.5K / / 03.11.2005
попробуй "рефрешить" форму потом или что нибудь такое.....
4.5K
09 марта 2007 года
StranikS
44 / / 03.02.2005
Наконец я решил эту проблему!!!!!!!!

Для всех кому интересно и тем, кто возможно с этим столкнется.
Ниже приведены модули ТЕСТОВОГО приложения. Отдельно помечены
обязательные добавления!

Вызов потока:

Код:
unit Unit1;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs;
type
  TForm1 = class(TForm)
    procedure FormClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
implementation
uses Thread_ImageCreate;
{$R *.dfm}

procedure TForm1.FormClick(Sender: TObject);
begin
if Assigned(ImageCreateThread)=false then
 begin
 form1.Caption:='Start';
 ImageCreateThread:=TImageCreateThread.Create(true);
 ImageCreateThread.FreeOnTerminate:=true;
 ImageCreateThread.Resume;
 end;
end;

end.


Модуль потока:

Код:
unit Thread_ImageCreate;

interface
uses
  Windows, Classes, Forms, Graphics, SysUtils;
type
  TImageCreateThread = class(TThread) //Новый класс
  private
    FStep:Integer;
  protected
    procedure ShowError;
    procedure Progress;
    procedure Execute; override;
  public
    constructor Create(CreateSuspended:Boolean);
    destructor Destroy; override;
  end;

var ImageCreateThread:TImageCreateThread;
implementation
uses Unit1;

constructor TImageCreateThread.Create(CreateSuspended:Boolean);
begin
 inherited Create(CreateSuspended);
 FStep:=0;
end;

destructor TImageCreateThread.Destroy;
begin
inherited;
ImageCreateThread:=nil;
end;

procedure TImageCreateThread.Progress;
begin
form1.Caption:=IntToStr(FStep);
end;

procedure TImageCreateThread.ShowError;
begin
Application.MessageBox(PChar('11111'),'Error',MB_ICONERROR);
end;

procedure TImageCreateThread.Execute;
var ZBitmap,BM:TBitmap;
      i:Integer;
begin
try
ZBitmap:=TBitmap.Create;
ZBitmap.PixelFormat:=pf4bit;
ZBitmap.Width:=4000;
ZBitmap.Height:=4000;

ZBitmap.Canvas.Lock;{NEWNEWNEWNENWNEWNEWNEW}

for i:=1 to 1000 do
 begin
 BM:=TBitmap.Create;

 BM.Canvas.Lock;{NEWNEWNEWNENWNEWNEWNEW}

 BM.LoadFromFile('c:\1.bmp');
 ZBitmap.Canvas.Draw(i*3,i*3,BM);
 
 BM.Canvas.Unlock;{NEWNEWNEWNENWNEWNEWNEW}
 
 FreeAndNil(BM);
 FStep:=i;
 Synchronize(Progress);
 end;
ZBitmap.SaveToFile('c:\3.bmp');

ZBitmap.Canvas.Unlock;{NEWNEWNEWNENWNEWNEWNEW}

FreeAndNil(ZBitmap);
except
 Synchronize(ShowError);
 end;
end;

end.


PS: В примере специально часто вызывается Synchronize, чтобы усугубить нарушения канвы (см. далее).

В данном примере НИКАКИХ нарушений в конечном "3.bmp" в ходе тестирования я не обнаружил.
Если же УБРАТЬ блокировку канвы, то как я уже говорил часть картинок "1.bmp" будет просто ПРОПАДАТЬ из общего ряда. Особенно сильно это будет заметно, если при работе потока преремещать Form1 по экрану в разные стороны. Мало того довольно часто при записи "3.bmp" в файл будет выскакивать сообщение:

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EOutOfResources with message 'Невозможно создать файл, так как он уже существует.
'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог