Является ли cwnd::GetSafeHwnd() и CWnd:: m hwnd ThreadSafe?

Я сталкиваюсь с многочисленными сбоями в приложении, которое сильно многопоточное.

чтение этих MSDN страница, техническое Примечание и эта статья о TLS, Я понял, что объекты cwnd в сопоставляются с hwnd в СС что-нить dependendent доступ к памяти.

Я собирался отделить все, что выглядит как cwnd thread-remote access, и преобразовать его в ссылки HWND, а затем использовать :: PostMessage как коммуникационный порт. ( И это представляет собой огромный объем работы, насколько я вижу в текущем коде на данный момент, на самом деле я разрабатывал решение, которое займет много времени, поэтому нам пришлось обсудить его).

но один из моих коллег действительно настаивал, что я просто сохраняю CWnd* в потоках иностранцев, принимаю политику:: PostMessage ok, но использую CWnd::GetSafeHwnd() или pMyCWnd->m_hWnd во внешних потоках, чтобы восстановить родной HWND.

Я пытаюсь это нигде я видел, что GetSafeHwnd () является threadsafe, и что объект CWnd находится в TLS, это значение в другом потоке отличается. Я ошибаюсь ? MSDN явно использует термин "неожиданные результаты".

какова ваша точка зрения, о вызове cwnd::GetSafehwnd() или pMyCWnd->m_hWnd во внешних потоках из потока создателя ?

У вас есть документация MSDN, в которой говорится, что это безопасно или нет.

3 ответов


CWnds не сопоставляются с HWNDs; HWNDs сопоставляются с CWnds, и это происходит на основе каждого потока. Объект CWnd не находится в TLS (как это будет работать?) но временные объекты CWnd создаются для каждого потока.

к временное cwnd объект из неправильного потока, безусловно, плохая идея (по причинам, описанным Марком Рэнсомом).

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

Если это беспокоит вас (потому что это явно не документировано), просто сделайте копию HWND и дайте потокам доступ к этому.

П. С. вот статья, которую вы связали с на английском языке.


GetSafeHwnd-это просто оболочка, которая проверяет, если this равно NULL, возвращает m_hWnd если нет и NULL, если это так. Это не будет более threadsafe, чем .

когда вы создаете временный CWnd*, MFC уничтожит его в точке, которую он считает безопасной, например, следующий проход через цикл сообщений. Если у вас есть несколько потоков, использующих MFC, ваш временный объект может быть уничтожен, пока вы все еще используете его. Ничто из того, что вы можете сделать из своего потока, не обнаружит этого ошибка.


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