2015-07-16 2 views
2

Я обычно прохожу рукоятку главной формы к другим потокам, чтобы они могли отправлять сообщения обратно в основной поток. Я видел, что 28 сентября 2013 года Реми Лебо заявил:Безопасна ли резьба TForm.Handle?

... свойство TWinControl.Handle также не является потокобезопасным. Вам следует использовать свойство TApplication.Handle или использовать AllocateHWnd(), чтобы создать собственное окно.

в this answer на вопрос о передаче строк.

Какая собственность ручка небезопасна? Это меняется в течение жизни программы?

+6

Да, это может измениться. Окно можно воссоздать. Если это так, старый дескриптор перестанет быть действительным. –

+1

[AllocateHWnd не является потокобезопасным] (http://www.thedelphigeek.com/2007/06/allocatehwnd-is-not-thread-safe.html) при некоторых обстоятельствах. [Отчет QC для этой проблемы] (http://qc.embarcadero.com/wc/qcmain.aspx?d=47559) –

+2

@DalijaPrasnikar 'AllocateHwnd' нельзя безопасно вызывать из потока - это не значит, что вы можете ' t вызвать его на основной поток и передать дескриптор, который он возвращает в рабочий поток. Хорошо. –

ответ

9

0 Как знать, как Handle не работает?

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

Это меняется в течение жизни программы?

Да, ручка окна может измениться, если окно заново создано.

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

В этом случае вы, вероятно, не имеете доступа к объекту Handle вдали от основной темы. Похоже, что (хотя я не вижу вашего кода) вы обращаетесь к Handle в основном потоке и передаете это значение другому потоку.

Однако рекреация окон - это проблема для вас. Поскольку ваше окно подвержено релаксации, вы просто не можете полагаться на этот инструмент, переживающий вашу нить. Будет ли ваше окно когда-либо воссоздано, трудно предсказать. VCL не выполняет отдых легко. Однако, на мой взгляд, гораздо лучше быть в безопасности, чем сожалеть. Итак, используйте AllocateHWnd и возьмите под контроль время жизни этого окна.

+3

Стоит отметить, что создание окна может быть вызвано чем-то таким же простым, как изменение свойства Form, которое может быть установлено только с вызовом 'CreateWindowEx'. –

+2

@J ...: С другой стороны, многие свойства окна, которые * могут * обновляться динамически без отдыха, * не обновляются соответствующим VCL. Обычно он просто заставляет полностью воссоздавать и применяет последние значения свойств в переопределенных методах 'CreateParams()' и 'CreateWnd()'. –

+0

Большинство из этих случаев объясняется тем, что не все версии Windows допускают определенные изменения стиля без повторного создания дескриптора окна. Если есть некоторые, которые не требуют обработки дескрипторов в версиях Windows, мы теперь поддерживаем (теперь XP находится в списке поддерживаемых версий), а затем сообщайте об этом на нашем портале качества (http://quality.embarcadero.com). –