Passing value to synchronize thread

前端 未结 3 1655
情话喂你
情话喂你 2020-12-16 04:06

I\'m new to thread, so i\'ve been trying with this for hours (i\'m using XE4),

i have a simple thread

type
  TSendThread = class(TThread)
  private         


        
相关标签:
3条回答
  • 2020-12-16 04:29

    Look at the various declarations of TThread.Synchronize(). You are trying to call the version that takes a TThreadMethod as input. TThreadMethod is parameter-less:

    TThreadMethod = procedure of object;
    

    That is why passing just t.Proc works but passing t.Proc('foo') does not.

    With that said, you are completely misusing TThread.Synchronize(). You don't need to create a TThread object in order to use the static version of Synchronize(). And if you do create a TThread object, make it actually do something, like this:

    type
      TSendThread = class(TThread)
      public
        fStr: String;
        procedure DoProc;
        procedure Proc(const S: string);
      protected
        procedure Execute; override;
      end;
    
      procedure TSendThread.Execute;
      begin
        Proc('foo');
      end;
    
      procedure TSendThread.Proc(const S: string);
      begin
        fStr := S;
        Synchronize(DoProc);
      end;
    
      procedure TSendThread.DoProc;
      begin
        ShowMessage(fStr);
      end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      t : TSendThread;
    begin
      t := TSendThread.Create(False);
      t.WaitFor;
      t.Free;
    end;
    

    However, because you are using XE4, Synchronize() also supports anonymous procedures as well, which would eliminate your TSendThread class completely in this example, eg:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      TThread.Synchronize(nil,
        procedure
        begin
          ShowMessage('foo');
        end
      );
    end;
    

    Update: given new info about what you REALLY want to do with your thread, you need to go about it like this instead:

    type
      TSendThread = class(TThread)
      private
        fURL, fMethod, fParam: string;
      protected
        procedure Execute; override;
      public
        constructor Create(aURL, aMethod, aParam: string);
      end;
    
    constructor TSendThread.Create(aURL, aMethod, aParam: string);
    begin
      inherited Create(False);
      fURL := aUrl;
      fMethod := aMethod;
      fParam := aParam;
    end;
    
    procedure TSendThread.Execute;
    begin
      // use fURL, fMethod, and fParam as needed...
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      t : TSendThread;
    begin
      t := TSendThread.Create('url', 'method', 'param');
      ...
    end;
    

    Or like this:

    type
      TSendThread = class(TThread)
      private
        fURL, fMethod, fParam: string;
        procedure GetValues;
      protected
        procedure Execute; override;
      end;
    
    procedure TSendThread.GetValues;
    begin
      fURL := ...;
      fMethod := ...;
      fParam := ...;
    end;
    
    procedure TSendThread.Execute;
    begin
      Synchronize(GetValues);
      // use fURL, fMethod, and fParam as needed...
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      t : TSendThread;
    begin
      t := TSendThread.Create(False);
      ...
    end;
    
    0 讨论(0)
  • 2020-12-16 04:40

    Another approach could be to write a wrapper function which takes no arguments, and call this parameterless method in Synchronize().

    0 讨论(0)
  • 2020-12-16 04:43

    Synchronize only takes a parameterless procedure, as I'm sure you've figured out. That means you have to use properties you get from the main thread in order to do certain things with it. For instance, my thread object is named monitor:

    Synchronize(UpdateCaption);  // as called in the thread code.
    
    procedure monitor.UpdateCaption;
    // synchronize procedure for monitor thread - updates memo on form.
    begin
      With Form1.CommandText.Lines do
        Add(TextString);
    end;
    

    Alternatively, you pass messages to the main thread, but this is a quick in a pinch way to do it.

    0 讨论(0)
提交回复
热议问题