2011-11-27 68 views
3

首先,我不确定允许工作线程禁用控件是一个好设计。但是,我很好奇,我可以安全地做到这一点,没有与GUI同步?我可以在工作线程中执行TDataSet.DisableControls而不用Synchronize()包装它吗?

在TDataSet的代码看起来是这样的:

procedure TDataSet.DisableControls; 
begin 
    if FDisableCount = 0 then 
    begin 
    FDisableState := FState; 
    FEnableEvent := deDataSetChange; 
    end; 
    Inc(FDisableCount); 
end; 

所以看起来安全的时候。 EnableControls的情况会有所不同。但DisableControls似乎只增加锁定计数器并分配在EnableControls期间触发的事件。

您认为如何?

+0

即使'Inc'本身不是线程安全的,如果你不用数据对齐编译。我强烈建议不要使用任何与GUI控件相关的控件**。 –

+1

此外,请考虑以下方案:线程进入,FDisableCount = 0,FDisableState = FState。上下文切换发生时,您的主线程递减FDisableCount并更改FDisableState(我想这就是EnableControls中会发生的情况,没有看过)。上下文切换发生,您的线程再次运行,但现在使用错误的FDisableState。 –

+0

谢谢你指出了列文。 – Wodzu

回答

0

这样做看起来很安全,但事情可能会出错,因为这些标志用于可能在您从线程调用此方法时正在执行的代码中。

我会同步调用DisableControls,因为你希望你的线程只有在没有控件使用它时才开始使用这个数据集。 对EnableControls的调用也可以同步,或者您可以使用PostMessage将消息发布到表单。这样,线程不必等待主线程。

但是我的直觉感觉告诉我,可能最好不要对GUI和线程使用相同的数据集。

0

没有查到实际的代码:只要你确定主线程当前不访问FDisableCount,FDisableState和FEnableEvent,它可能是安全的。这里有可能出现比赛状况。

我仍然建议您从主线程中调用DisableControls。

相关问题