Почему я получаю Вне системных ресурсов, когда поток вызывает асинхронный этот метод - PullRequest
1 голос
/ 17 марта 2012

У меня есть TThread, и он вызывает следующую функцию:

//------------------------------------------------------------------------------
procedure TfrImageShow.Load(bmBitmap:TBitmap);
begin

   self.bmBitmapCopy.Width:=bmBitmap.Width;
   self.bmBitmapCopy.Height:=bmBitmap.Height;
   self.bmBitmapCopy.Canvas.Draw(0,0,bmBitmap);
end;

И мой поток в Execution вызывает этот метод, и через некоторое время он выдает ошибку: Out of system resources?Почему, потому что Bitmap не является компонентом VCL.Он также использует критический раздел

TThread.execute
begin
 ....
   csCriticalSection.Enter;
       frImage.Load(bmBitmap);
   csCriticalSection.Leave;
....
end;

Также у меня есть вопрос, является ли этот критический раздел полезным (я упоминаю, что другого потока нет), только иногда поток приложения читает bmBitmapCopy из

1 Ответ

0 голосов
/ 18 марта 2012

Защита доступа к GUI (основной поток VCL) из потока с critical secion - неправильный способ справиться с этим.

Поскольку VCL не доступен напрямую из других потоков, поток должен синхронизировать вызов к VCL.

пример (если ваша версия Delphi поддерживает anonymous methods):

Synchronize(
  procedure
    begin
      frImage.Load(bmBitmap);
    end);

Метод Synchronize будет заменен на основной поток во время выполнения.

Если у вас более старая версия Delphi, добавьте метод в ваш класс TThread и вызовите Load оттуда:

TThread.CallLoad;
begin
  frImage.Load(bmBitmap);
end;

TThread.Execute;
begin
  ...
  Synchronize( Self.CallLoad);
  ...
end;

Использование critical section заключается в сериализации доступа двух (или более) потоков к общему объекту / переменной и т. Д. Но в этом случае обращения к ресурсам VCL из потока строго запрещены.

...