Было бы проще просто создать отдельный поток с собственной очередью сообщений для ваших сокетов? Я не думаю, что CAsyncSocket нужно создавать в основной очереди сообщений, просто в какой-то очереди сообщений. См. документацию по CWinThread, чтобы узнать, как создать отдельный поток с собственной очередью сообщений, совместимой с MFC.
К сожалению, крайне важно, чтобы вы вызывали все операции с сокетами из контекста нового потока. MFC использует глобальное состояние в скрытых классах, которые используют локальное хранилище потока для хранения информации о потоке, и эта информация используется во многих методах CAsynchSocket. Это означает, что CAsynchSocket имеет сходство с потоком, и вы всегда должны использовать и создавать его в любом потоке, который должен быть его насосом сообщений.
Одним из подходов может быть создание CWinThread, создание собственного пользовательского скрытого окна MFC в этом потоке (путем создания окна в контексте этого потока) и создание сообщений и обработчиков сообщений в этом окне для всех операций сокета (создание, подключение и т. д.) вы делаете. Убедитесь, что поток перекачивает сообщения (это делает метод "Run()"), а затем публикуйте/отправляйте сообщения в ваше окно для управления вашими сокетами.
Кроме того, помните, что обратные вызовы из вашего сокета будут поступать в отдельный поток, чем ваш пользовательский интерфейс или рабочие потоки. Вам нужно будет побеспокоиться об условиях гонки и, возможно, о проблемах привязки потоков GUI, если вы обновляете объекты GUI.
Если вы беспокоитесь о влиянии на дизайн, просто создайте собственный прокси-объект CThreadSafeAsynchSocket и делегируйте его реальной реализации посредством передачи сообщений скрытому окну. Вы можете использовать SendMessage для блокировки операций и PostMessage для асинхронных операций. Если вы оберните конструктор в фабричный объект, вы можете отложить создание потока сокета до тех пор, пока он не понадобится.
Последнее, о чем я могу думать, это то, что вам нужно будет определить, когда все ваши прокси исчезнут, и закрыть поток. Вы можете использовать глобальный счетчик ссылок, управляемый конструкторами/деструкторами CThreadSafeAsynchSocket, чтобы определить, когда следует закрыть поток. Если не закрыть поток, ваше приложение будет зависать со скрытым окном даже после того, как вы закроете главное окно приложения.
person
David Gladfelter
schedule
06.04.2009