Я похож для добавления моего собственного 0.02c
приблизительно два конкурирующих соображения при рассмотрении общей проблемы того, где расположить обработку исключений:
"шире" ответственность try-catch
блок (т.е. вне цикла в Вашем случае) означает, что при изменении кода в некоторой более поздней точке, можно по ошибке добавить строку, которая обрабатывается существующим catch
блок; возможно неумышленно. В Вашем случае это менее вероятно, потому что Вы явно ловите NumberFormatException
, Чем "более узкий" ответственность try-catch
блок, тем более трудный рефакторинг становится. Особенно, когда (как в Вашем случае) Вы выполняете "нелокальную" инструкцию из catch
блок (return null
оператор).
В нашем приложении мы устанавливаем условие "завершения", а затем используем самоподключение к порту, который прослушивает поток, чтобы он просыпался, записывал условие завершения и завершал работу.
Вы также можете проверить реализацию форсирования - если они выполняют только простое чтение из сокета (т. Е. Не используют что-то вроде WaitForMultipleObjects внутри самих себя), то вы, вероятно, можете сделать вывод, что нет ничего, что можно было бы просто и чисто разблокировать нить. Если они ожидают нескольких объектов (или порта завершения), вы можете покопаться, чтобы увидеть, доступна ли извне возможность разбудить блокирующий поток.
Наконец, вы можете убить поток - но вам придется идти за пределами boost, чтобы сделать это, и понять последствия, такие как зависание или утечка ресурсов.
Я не нашел простого способа сделать это. Предположительно, есть способы отменить Win32 IOCP, но он не работает в Windows XP. MS исправила это для Windows Vista и 7. Рекомендуемый подход для отмены asio async_read
или async_write
- закрыть сокет.
[деструктор] ожидают завершения обработчиков
[завершение], если разрыв завершен, и мы просто потерпели неудачу из-за закрытия сокета, уведомить деструктор, что обработчики завершения завершены.
Будьте осторожны, если решите реализовать это. Закрыть сокет довольно просто. Однако «ждать обработчиков завершения» - это еще не все. Есть несколько тонких угловых случаев и состояний гонки, которые могут возникнуть, когда поток сервера и его деструктор взаимодействуют.
Это было достаточно тонко, чтобы мы создали оболочку завершения (похожую на io_service :: strand
только для обработки синхронная отмена всех ожидающих обратных вызовов завершения.
Лучший способ состоит в том, чтобы создать Socketpair ()
, (все, что находится в Boost :: Asio
Parlance), добавьте конец читателя на Контур событий, затем закройте писатель. Вы будете немедленно проснуться с Eof Event на этой розетке.
Тема должна затем добровольно закрыться.
Spawner нити должен в его деструктора, иметь следующее:
~object()
{
shutdown_queue.shutdown(); // ask thread to shut down
thread.join(); // wait until it does
}