Delphi : How to create and use Thread locally?

后端 未结 3 1901
既然无缘
既然无缘 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条回答
  •  花落未央
    2021-02-10 15:32

    Yes you can do that.

    The way I would do it is to add an event-handler to your form.
    You'll have to link the event-handler in code, but that's not that difficult.

    Create a thread like so:

    TMyEventHandler = procedure(Sender: TObject) of object;
    
    type
      TMyThread = class(TThread)
      strict private
        FDoneEvent: TMyEvent;
        FDone: boolean;
        FQuery: TFDQuery;
        constructor Create(DoneEvent: TMyEventHandler; Query: TFDQuery);
        procedure Execute; override;
        function GetQuery: TFDQuery;
      public
        property Query read GetQuery;
      end;
    
      TForm1 = class(TForm)
        FDQuery1: TFDQuery;  //Do not connect the FDQuery1 to anything!
        DataSource1: TDataSource;
        DBGrid1: TDBGrid;
      private
        FOnThreadDone: TMyEventHandler;
        FMyThread: TMyThread;
        procedure DoThreadDone;
        procedure ThreadDone;
      public
        property OnThreadDone: TMyEventHandler read FOnThreadDone write FOnThreadDone;
      ....
    
    implementation
    
    constructor TMyThread.Create(DoneEvent: TMyEvent; Query: TFDQuery);
    begin
      inherited Create(true);
      FDoneEvent:= DoneEvent;
      FQuery:= Query;
      Start;
    end;
    
    procedure TMyThread.Execute;
    begin
      //Do whatever with the query
      //when done do:
      FDone:= true;
      Synchonize(Form1.DoThreadDone);
    end;
    
    function TMyThread.GetQuery: TFDQuery;
    begin
      if not Done then Result:= nil else Result:= FQuery;
    end;
    
    procedure TForm1.DoThreadDone;
    begin
      if Assigned(FOnThreadDone) then FOnThreadDone(Self);
    end;
    
    procedure TForm1.ThreadDone(Sender: TObject);
    begin
      ShowMessage('Query is done');
      //Now you can display the result of the query, by wiring it
      //to a dataset.
      MyDataSource1.Dataset:= FMyThread.Query;
      FMyThread.Free;
    end;
    
    procedure TForm1.StartTheQuery;
    begin
      OnThreadDone:= Self.ThreadDone;
      FMyThread:= TMyThread.Create(OnThreadDone, FDQuery1);
    end;
    

    Now the query will run in the background and signal your event handler when it is done. Meanwhile you can do all the mousing around and user interaction you want without having to worry. Note that you cannot use FDQuery1 at all whilst the thread is using it, and you cannot have FDQuery1 wired to a DataSource whilst it's the thread is running with it.
    Leave it unwired and wire it in the ThreadDone event handler as shown.

提交回复
热议问题