Pass parameters to Synchronize procedure call

delphi, delphi-2009, multithreading, synchronize

Solution

Use anonymous methods.

As you can read in the manual for the `TThread.Synchronize`

Synchronize(
  procedure
  begin
    Form1.Memo1.Lines.Add('Begin Execution');
  end);

In the example above the referenced variable `Form1` would kind of like be copied and saved until the procedure gets executed (that is called variable capture).

Note: David objects to the idea of "copied variable" and he probably is right. However discussing all the corner cases and implementation details would be an overkill. His comparison to "global variable" OTOH would probably have troubles with recursive procedures, etc. All the simple to grasp analogies are very rough and tilted one way or another ISTM.

Your anonymous procedure should use your variables `val1` and `val2` and they then should get captured too

http://docwiki.embarcadero.com/Libraries/XE5/en/System.Classes.TThread.Synchronize

Problem

When creating a thread object, I want to call code from the application that needs to be synchronized. The problem is that I don't know how to call `Synchronize` for an application function with parameters. Say we have ``` procedure ThreadObject.Execute; var val1,val2:integer; Star:string; begin Synchronize(funcyfunc); //how to pass val1,val2,star here? end; ``` where `funcyfunc` is defined as follow ``` procedure OtherClass.funcyfunc(param1,param2:integer;spok:string); begin letsCallFriends(spok,param1); letsCallFriends(spok,param2); end; ``` now the odd solution to this would be to say in ThreadObject private ``` private star:string; val1,val2:integer; procedure starVal; ``` and in the implementation we do ``` procedure ThreadObject.starVal; begin funcyfunc(Star,val1,val2); end; ``` and in the thread execute we change to ``` procedure ThreadObject.Execute; var val1,val2:integer; Star:string; begin Synchronize(starVal); //how to pass val1,val2,star here? end; ``` but this is a hassle, as for each procedure call there must be a global variable. Is there a better way? code: ``` unit ThreadObject; interface uses Classes; type TThreadObject= class(TThread) private star:string; val1,val2:integer; procedure starVal; protected procedure Execute; override; //assume we have a constructor that ini the star val1 val2. end; implementation { TThreadObject } procedure ThreadObject.Execute; var val1,val2:integer; Star:string; begin Synchronize(starVal); //how to pass val1,val2,star here? end; procedure ThreadObject.starVal; begin funcyfunc(Star,val1,val2); end; end. ```

Original source

Related problems