Могу ли я выполнить TDataSet.DisableControls в рабочем потоке, не помещая его в Synchronize ()? - PullRequest
4 голосов
/ 27 ноября 2011

Прежде всего, я не уверен, что это хороший дизайн, позволяющий рабочему потоку отключать элементы управления. Тем не менее, мне интересно, могу ли я сделать это безопасно без синхронизации с графическим интерфейсом?

Код в TDataSet выглядит следующим образом:

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

Так что это выглядит безопасно. Ситуация была бы другой в случае EnableControls. Но DisableControls, кажется, только увеличивает счетчик блокировки и назначение события, которое запускается во время EnableControls.

Что ты думаешь?

Ответы [ 2 ]

0 голосов
/ 27 ноября 2011

Не просматривая фактический код: это может быть безопасно, если вы можете быть уверены, что основной поток в настоящее время не имеет доступа к FDisableCount, FDisableState и FEnableEvent. Здесь есть возможность состояния гонки.

Я бы по-прежнему рекомендовал вызывать DisableControls из основного потока.

0 голосов
/ 27 ноября 2011

Это выглядит безопасным, но все может пойти не так, потому что эти флаги используются в коде, который может быть в середине выполнения в тот момент, когда вы вызываете этот метод из вашего потока.

Я бы синхронизировал вызов с DisableControls, потому что вы хотите, чтобы ваш поток начал использовать этот набор данных, только если его не используют никакие элементы управления.Вызов EnableControls также может быть синхронизирован, или вы можете отправить сообщение в форму, используя PostMessage.Таким образом, поток не должен ждать основного потока.

Но мои интуитивные чувства подсказывают мне, что может быть лучше вообще не использовать один и тот же набор данных для графического интерфейса и потока.

...