将参数传递给Synchronize过程调用

时间:2014-01-28 15:32:52

标签: multithreading delphi delphi-2009 synchronize

创建线程对象时,我想从需要同步的应用程序中调用代码。问题是我不知道如何使用参数调用Synchronize应用程序函数。

说我们有

procedure ThreadObject.Execute;
var
  val1,val2:integer;
  Star:string;
begin
  Synchronize(funcyfunc); //how to pass val1,val2,star here?
end;

其中funcyfunc定义如下

procedure OtherClass.funcyfunc(param1,param2:integer;spok:string);
begin
   letsCallFriends(spok,param1);
   letsCallFriends(spok,param2);
end;

现在奇怪的解决方法是在ThreadObject private

中说
private
  star:string;
  val1,val2:integer;
  procedure starVal;

在我们的实施中

procedure ThreadObject.starVal;
begin
  funcyfunc(Star,val1,val2);
end;

并在线程执行中我们改为

procedure ThreadObject.Execute;
var
  val1,val2:integer;
  Star:string;
begin
  Synchronize(starVal); //how to pass val1,val2,star here?
end;

但这很麻烦,因为每个过程调用都必须有一个全局变量。还有更好的方法吗?

代码:

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.

2 个答案:

答案 0 :(得分:8)

使用匿名方法

您可以阅读TThread.Synchronize

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

在上面的示例中,引用变量 Form1有点像复制并保存,直到程序执行(称为变量捕获)。

注意:David反对“复制变量”的想法,他可能是对的。然而,讨论所有角落案例和实施细节将是一种矫枉过正。他与“全局变量”OTOH的比较可能会对递归程序等造成麻烦。所有简单易懂的类比都是非常粗糙的,并且倾向于这样或那样的ISTM。

您的匿名程序应该使用您的变量val1val2,然后它们也应该被捕获

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

答案 1 :(得分:2)

如果您使用的是不支持匿名方法的旧版Delphi,则可以在课堂上创建“参数”字段。即。

procedure ThreadObject.Execute;
var
  val1,val2:integer;
  Star:string;
begin
  FVal1 := val1;
  FVal2 := val2;
  FStar := Star;
  Synchronize(funcyfunc);
end;

procedure ThreadObject.FuncyFunc;
begin
  //Do stuff with FVal1, FVal2 and FStar
end;

请注意,这些全球 它也很安全,因为Synchronize的要点是确保两个线程相互协调。因此,如果您没有其他线程尝试访问相同的数据,则不会有任何竞争条件。

是的,它有点“笨拙”,但这是在较新版本的Delphi中使用匿名方法的优势。