Multithreading 我可以在工作线程中执行TDataSet.DisableControls而不使用Synchronize()包装它吗?

Multithreading 我可以在工作线程中执行TDataSet.DisableControls而不使用Synchronize()包装它吗?,multithreading,delphi,synchronization,dataset,delphi-2009,Multithreading,Delphi,Synchronization,Dataset,Delphi 2009,首先,我不确定允许工作线程禁用控件是否是一个好的设计。然而,我很好奇,如果不与GUI同步,我能安全地完成它吗 TDataSet中的代码如下所示: procedure TDataSet.DisableControls; begin if FDisableCount = 0 then begin FDisableState := FState; FEnableEvent := deDataSetChange; end; Inc(FDisableCount); end;

首先,我不确定允许工作线程禁用控件是否是一个好的设计。然而,我很好奇,如果不与GUI同步,我能安全地完成它吗

TDataSet中的代码如下所示:

procedure TDataSet.DisableControls;
begin
  if FDisableCount = 0 then
  begin
    FDisableState := FState;
    FEnableEvent := deDataSetChange;
  end;
  Inc(FDisableCount);
end;
这样做看起来很安全。在启用控制的情况下,情况会有所不同。但DisableControls似乎只会增加锁计数器和分配在EnableControls期间触发的事件


你认为如何?

这样做是安全的,但是事情可能出错,因为这些标志在代码中使用,可能是在从线程调用这个方法的时候执行的。p> 我将同步对DisableControls的调用,因为您希望您的线程仅在没有控件使用该数据集时才开始使用该数据集。 对EnableControls的调用也可以同步,或者您可以使用PostMessage将消息发布到表单中。这样,线程就不必等待主线程


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

在没有查找实际代码的情况下:这可能是安全的,只要您能够确保主线程当前没有访问FDisableCount、FDisableState和fenablevent。这里有可能出现比赛情况


我仍然建议您在主线程内调用DisableControls。

如果不使用数据对齐进行编译,即使是
Inc
本身也不是线程安全的。我强烈建议不要使用任何控件链接到GUI控件。进一步,请考虑下面的场景:线程进入,FDABABLeCUNT=0,FDABABLeTe= FStand。发生上下文切换时,主线程递减FDisableCount并更改FDisableState(我想这是EnableControls中会发生的情况,我还没看过)。一个上下文切换发生,你的线程再次运行,但是现在使用的是错误的FDisableState。谢谢你指出这一点。