Могу ли я прочитать свойства элемента управления VCL в потоке без графического интерфейса пользователя?

Является ли потокобезопасным, если поток асинхронно считывает информацию из элементов управления VCL в Delphi?

eg.

procedure TMyThread.Execute;
var bOK:Boolean; 
    iOK:Integer;
begin
   while not terminated do
   begin
      bOk:=MyForm.cbCheckBox.Checked;
      iOK:=MyForm.Left;
      sleep(20);
   end;
end;

Если это не потокобезопасный, как мне сделать, чтобы поймать событие, когда флажок изменил свое свойство.


person user558126    schedule 06.01.2013    source источник
comment
Как сказал Дэвид, работать напрямую с vcl небезопасно. В приведенной выше ссылке состояние элемента управления vcl хранится в переменной. В данном случае это было логическое значение, и это безопасно. Но другие типы могут быть небезопасными.   -  person LU RD    schedule 06.01.2013


Ответы (1)


Нет, это небезопасно. Ваш код может привести к созданию дескриптора окна с привязкой к неправильному потоку.

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

person David Heffernan    schedule 06.01.2013
comment
Итак, мне нужно использовать метод Synchronize? - person user558126; 06.01.2013
comment
Как мне решить мою проблему? Чтобы поймать событие, когда флажок был изменен? - person user558126; 06.01.2013
comment
Что ж, вы могли бы, но, как я уже сказал, вам лучше вообще не трогать графический интерфейс. Ваш базовый объект модели должен содержать состояние. Прочтите это оттуда. Не храните свое состояние в объектах графического интерфейса. - person David Heffernan; 06.01.2013
comment
Как мне решить мою проблему? Чтобы поймать событие, когда флажок был изменен? - - person user558126; 06.01.2013
comment
Решите проблему, используя метод, описанный в ответе. Сохраняйте состояние вашего приложения в объекте, обычно известном как представление. Пусть ваш графический интерфейс будет отображением этой модели. Когда пользователь вносит изменения в графический интерфейс, внесите эти изменения в модель. Тогда вашим рабочим потокам не нужно будет касаться VCL, и ваши проблемы исчезнут. Прочтите о модели-представлении-контроллере. - person David Heffernan; 06.01.2013
comment
и как мне изменить свойства модели - person user558126; 06.01.2013
comment
Вызов методов, присвоение свойствам и т. Д. Ничего особенного, просто простое ООП-кодирование на Delphi. - person David Heffernan; 06.01.2013
comment
Итак, я сделаю объект, который будет доступен из графического интерфейса и потока. Когда свойство будет изменено, графический интерфейс будет запускать событие, а затем графический интерфейс изменит свойство этого общего объекта? Можете дать ссылку с примером исходного кода? - person user558126; 06.01.2013
comment
давайте продолжим обсуждение в чате - person user558126; 06.01.2013
comment
Почему бы просто не отправить (опубликовать) сообщение в поток из потока графического интерфейса при изменении статуса флажка? - person Remko; 06.01.2013