2011-11-27 25 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。

相關問題