【发布时间】:2014-02-13 06:10:24
【问题描述】:
我有这个主窗体
TForm1 = class(TForm)
fReceiver: TMessageReceiver;
fCS: TCriticalSection;
constructor Create(aOwner: TComponent); override; **Create Critcal section**
destructor Destroy(); override; **Delete critical section**
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
fcs.Acquire;
//Perform Action
fcs.Release;
end;
TMessageReceiver= class(TReceiver)
private
fFrame: TForm1;
public
constructor Create(aFrame: TForm1);
destructor Destroy(); override;
function HandleMessage(aUserName: string): boolean; override;
end;
function TMessageReceiver.HandleMessage(aUserName: string): boolean;
begin
fFrame.fcs.Acquire;
//Do Lengthy OP
fFrame.fcs.Release;
end;
我有这两个类,其中 TMessageReceiver 在一个线程中被调用。我尝试在这两个类之间进行同步。调用句柄消息后,如果我尝试单击按钮,它将进入关键部分块,即使它已经在 HandleMessage 中获取。 我不知道这段代码有什么问题。
任何建议都会有很大帮助。
【问题讨论】:
-
你显示的代码没有问题,所以一定是你没有显示的代码有问题。请提供SSCCE。
-
代码似乎没问题。你不要让我们从 TMessageReceiver 看到 Create。所以会出现一个问题:它是同一个关键部分,还是周围有多个 form1 实例,因此有多个关键部分?
-
@RemyLebeau:这是一个非常大的代码,所以我不知道如何显示它。为了简化事情,我删除了关键部分的所有用法,只在按钮单击中使用它并删除了版本。现在,当我单击按钮两次时,即使我没有释放它,它也会进入块。为什么会这样?
-
@RitsaertHornstra:我在表单 1 实例的构造函数和析构函数中放置了一个调试点,它被调用一次。有什么方法可以确定是否有多个临界区实例?
-
@Jeeva:我不是要你的全部代码,只是一个小的SSCCE 重现了同样的问题。至于其余的,当一个线程已经获得了 CS 锁的所有权时,它可以根据需要多次重新进入同一个 CS。唯一的要求是每个 Acquire 必须有一个 Release 以保持 CS 的内部锁计数器平衡。
标签: multithreading delphi