Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.

ThreadSnapshot in Thread

Post Reply
User avatar
ПетрСоболев
Posts: 4
Joined: Thu Jan 11, 2024 1:41 pm

ThreadSnapshot in Thread

Post by ПетрСоболев »

The problem is this. For each screenshot I create a new thread. I pass the name of the screenshot I want to receive to the stream. The thread is running and must exit. If I set the thread to complete automatically, the program closes after the first screenshot is taken. Now the code works, but the size of the memory occupied by the program is constantly growing. How to solve this problem?

Code: Select all

procedure TForm1.GetImageBS(Lac,Sid,zadanie,UserID,ZOOM:string);
Var
..
begin
 var FThread : TCEFBrowserThread                  := TCEFBrowserThread.Create(HtmLFileName, 1024, 1024);
      FThread.OnError             := Thread_OnError;
      FThread.OnSnapshotAvailable := Thread_OnSnapshotAvailable;
      FThread.OnTerminate := ThreadTerminated;
      FThread.L:=La;
      FThread.s:=si;
      FThread.UserID:=UID;
      FThread.zadanie:=zadanie;
      FThread.HTML:=HtmLFileName;
      if (ZO<>'') and TrySTRTOINT(z,Temp) then  FThread.z:=zo else  FThread.z:='';
      FThread.Start;
end;
...

procedure TForm1.Thread_OnSnapshotAvailable(Sender: TObject);
var
  TempBitmap : TBitmap;
   JPEG: TJPEGImage;
   SendRes:boolean;
   FThread : TCEFBrowserThread absolute Sender;
begin
  TempBitmap    := nil;

  memo1.Lines.Add('Запущен поток: '+FThread.L+'_'+FThread.s+'_'+FThread.UID+'_'+FThread.zadanie);
  JPEG := TJPEGImage.Create;

  if (FThread <> nil) and FThread.CopySnapshot(TempBitmap) then
    begin
      JPEG.Assign(TempBitmap);
      Image1.Picture.Assign(JPEG);
      if fileexists(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.L+'_'+FThread.s+FThread.z+'.jpg') then
      begin
          if not (FThread.UID='') then
          begin
             ....
          end;
        FThread.TerminateBrowserThread;

        exit;
      end;

      JPEG.SaveToFile(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.L+'_'+FThread.s+FThread.z+'.jpg');
      JPEG.Free;
      if not (FThread.UserID='') then
      begin
       .....
      end;

      FThread.TerminateBrowserThread;
    end;


end;
Last edited by ПетрСоболев on Sun Jan 14, 2024 2:30 pm, edited 1 time in total.
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: ThreadSnapshot in Thread

Post by salvadordf »

Hi,

The TerminateBrowserThread call only destroys the browser in the thread but you also need to destroy the thread.

I would recommend using the same thread or a limited number of threads to take all the screenshots.

The WebpageSnapshot demo do this and it uses the same thread when you click the Go button.
User avatar
ПетрСоболев
Posts: 4
Joined: Thu Jan 11, 2024 1:41 pm

Re: ThreadSnapshot in Thread

Post by ПетрСоболев »

I need to pass the name of the browser's output snapshot to the stream. And often a situation arises when you need several snapshots at the same time, but one thread cannot cope with this. That's why I create my own stream for everyone. How can I complete my task?
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: ThreadSnapshot in Thread

Post by salvadordf »

Set FreeOnTerminate to True in TCEFBrowserThread.Create and the thread will free all its resources after the TerminateBrowserThread call.
User avatar
ПетрСоболев
Posts: 4
Joined: Thu Jan 11, 2024 1:41 pm

Re: ThreadSnapshot in Thread

Post by ПетрСоболев »

That's what I did. Installed FreeOnTerminate. After the thread completes, the entire program closes. I can't understand why.
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: ThreadSnapshot in Thread

Post by salvadordf »

Sorry. I forgot that TChromiumCore.FCompHandle needs to be allocated and deallocated in the main application thread.

Set the FreeOnTerminate to FALSE again and destroy the threads using this code :

Code: Select all

  if (FThread <> nil) then
    begin
      if FThread.TerminateBrowserThread then
        FThread.WaitFor;

      FreeAndNil(FThread);
    end;
User avatar
ПетрСоболев
Posts: 4
Joined: Thu Jan 11, 2024 1:41 pm

Re: ThreadSnapshot in Thread

Post by ПетрСоболев »

I wrote the code in the Thread_OnSnapshotAvailable procedure. And nothing works. Threads multiply and do not terminate. Maybe I'm doing something wrong?

Code: Select all

procedure TForm1.Thread_OnSnapshotAvailable(Sender: TObject);
var
  TempBitmap : TBitmap;
   JPEG: TJPEGImage;
   SendRes:boolean;
   FThread : TCEFBrowserThread absolute Sender;
begin
  TempBitmap    := nil;

  memo1.Lines.Add('Запущен поток: '+FThread.L+'_'+FThread.s+'_'+FThread.UID+'_'+FThread.zadanie);
  JPEG := TJPEGImage.Create;

  if (FThread <> nil) and FThread.CopySnapshot(TempBitmap) then
    begin
      JPEG.Assign(TempBitmap);
      Image1.Picture.Assign(JPEG);
      if fileexists(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.L+'_'+FThread.s+FThread.z+'.jpg') then
      begin
          if not (FThread.UID='') then
          begin
          FTelegram.SetUserID(FThread.UID);
          FTelegram.sendPhoto(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.Lac+'_'+FThread.s+FThread.z+'.jpg','Задание:'+FThread.zadanie+' L='+FThread.L+' C='+FThread.s,SendRes);
          end;
        //FThread.TerminateBrowserThread;
        if (FThread <> nil) then
          begin
            if FThread.TerminateBrowserThread then
              FThread.WaitFor;

            FreeAndNil(FThread);
          end;

        exit;
      end;

      JPEG.SaveToFile(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.L+'_'+FThread.s+FThread.z+'.jpg');
      JPEG.Free;
      if not (FThread.UserID='') then
      begin
      FTelegram.SetUserID(FThread.UID);
      FTelegram.sendPhoto(extractfilepath(Application.ExeName)+'\BS_image\'+FThread.L+'_'+FThread.s+FThread.z+'.jpg','Задание:'+FThread.zadanie+' L='+FThread.L+' C='+FThread.s,SendRes);
      end;

      //FThread.TerminateBrowserThread;
        if (FThread <> nil) then
          begin
            if FThread.TerminateBrowserThread then
              FThread.WaitFor;

            FreeAndNil(FThread);
          end;


    end;


end;
User avatar
salvadordf
Posts: 4057
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: ThreadSnapshot in Thread

Post by salvadordf »

Add these points :
  • Keep a list of TCEFBrowserThread instances in the main form and add each new instance as soon as you create it.
  • When a thread must be destroyed send a custom windows message to the main form with the ThreadID as one of the parameters.
  • Implement a procedure in the main form that is executed when the form receives the custom message, search the ThreadID value in the thread list and destroy that thread.
In this way the threads are created and destroyed in the main application thread.
Post Reply