I have a simple program which takes screenshots of the screen a few times per second. I created a simple code which does that and I can run it as many times as I want and it works alright. But when I put the same code into a thread and run it, the memory usage starts rising until the application runs out of resources (in about 10 seconds) and then the thread gets stuck of course.
For testing I have a form with two buttons. One runs the mentioned code and the second one starts a thread which runs the same code. I can even hold Enter key on the first button and there is no memory leak but when I click the second button the thread instantly keeps rising the memory usage (I can even stop it using stop_thread variable but the memory usage stays high).
...
type
TMyThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
var
Form1: TForm1;
stop_thread: Boolean;
my_thread: TMyThread;
...
constructor TMyThread.Create();
begin
inherited Create(true);
FreeOnTerminate:=true;
Suspended:=true;
end;
destructor TMyThread.Destroy;
begin
inherited;
end;
procedure TMyThread.Execute;
var screen_bmp: TBitmap;
desktop_hdc: HDC;
begin
while(stop_thread=false)do
begin
screen_bmp:=TBitmap.Create;
screen_bmp.PixelFormat:=pf32bit;
screen_bmp.Height:=Screen.Height;
screen_bmp.Width:=Screen.Width;
desktop_hdc:=GetWindowDC(GetDesktopWindow);
BitBlt(screen_bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, desktop_hdc, 0, 0, SRCCOPY);
ReleaseDC(GetDesktopWindow, desktop_hdc);
screen_bmp.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var screen_bmp: TBitmap;
desktop_hdc: HDC;
begin
screen_bmp:=TBitmap.Create;
screen_bmp.PixelFormat:=pf32bit;
screen_bmp.Height:=Screen.Height;
screen_bmp.Width:=Screen.Width;
desktop_hdc:=GetWindowDC(GetDesktopWindow);
BitBlt(screen_bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, desktop_hdc, 0, 0, SRCCOPY);
ReleaseDC(GetDesktopWindow, desktop_hdc);
screen_bmp.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
stop_thread:=false;
Button2.Enabled:=false;
my_thread:=TMyThread.Create;
my_thread.Resume;
end;
I know the problem has something to do with the BitBlt line, because without it there is no memory leak. But I don't understand what and why is happening. And why it isn't happening when the code is running from the main thread. Even when I put the Button1 code into a cycle and run it endlessly from the main thread, the memory usage stays low. What's the difference?
Thank you for any advice!