Delphi : How to create and use Thread locally?

后端 未结 3 1896
既然无缘
既然无缘 2021-02-10 15:03

My database is in a VPS and I should get some query from my tables

Because of getting query from server taking long time ( depending on Internet speed ! ) , I want to us

3条回答
  •  闹比i
    闹比i (楼主)
    2021-02-10 15:33

    What you describe is not the best use of a thread. The calling code is blocked until the thread is finished. That negates the use of running code in parallel at all. You could just perform the query directly instead:

    procedure Requery;
    var
      ...
    begin
      ...
      // run query
      // do next jobs with query
      ...
    end;
    

    That being said, since you are using XE6, you can create a "local" thread by using the TThread.CreateAnonymousThread() method, specifying an anonymous procedure that "captures" the variables you want it to work with, eg:

    procedure Requery;
    var
      Event: TEvent;
      H: THandle;
    begin
      Event := TEvent.Create;
      try
        TThread.CreateAnonymousThread(
          procedure
          begin
            try
              // run query in thread
            finally
              Event.SetEvent;
            end;
          end
        ).Start;
        H := Event.Handle;
        while MsgWaitForMultipleObjects(1, H, False, INFINITE, QS_ALLINPUT) = (WAIT_OBJECT_0+1) do
          Application.ProcessMessages;
      finally
        Event.Free;
      end;
    
      // Do next jobs with query
      ...
    end;
    

    Alternatively:

    procedure Requery;
    var
      Thread: TThread;
      H: THandle;
    begin
      Thread := TThread.CreateAnonymousThread(
        procedure
        begin
          // run query in thread
        end
      );
      try
        Thread.FreeOnTerminate := False;
        H := Thread.Handle;
        Thread.Start;
        while MsgWaitForMultipleObjects(1, H, False, INFINITE, QS_ALLINPUT) = (WAIT_OBJECT_0+1) do
          Application.ProcessMessages;
      finally
        Thread.Free;
      end;
    
      // Do next jobs with query
      ...
    end;
    

    However, threading is more useful when you let it run in the background while you do other things and then you act when the thread has finished its work. For example:

    procedure TMyForm.Requery;
    var
      Thread: TThread;
    begin
      Thread := TThread.CreateAnonymousThread(
        procedure
        begin
          // run query in thread
        end
      );
      Thread.OnTerminate := QueryFinished;
      Thread.Start;
    end;
    
    procedure TMyForm.QueryFinished(Sender: TObject);
    begin
      if TThread(Sender).FatalException <> nil then
      begin
        // something went wrong
        Exit;
      end;
      // Do next jobs with query
    end;
    

提交回复
热议问题