Listening, конечно же, изменяется на false для окончания обработки, но ведь к нему дойдет только при следующем сообщении из сети. А мне надо как-то прервать ChatSocketListener.Accept().
Либо, действительно, асинхронно сделать через BeginAccept (http://msdn.microsoft.com/ru-ru/library/system.net.sockets.socket.beginaccept(v=vs.110).aspx), либо, как вариант, создать клиентский сокет, и по действию, которое Вам нужно (выход, как я понял), сделать соединение и завершить его…
1. Использовать APM и метод BeginAccept. Оптимальный выбор. Так же можно обернуть в TAP через wrapper и использовать с await.
2. Вынести ссылку на сокет в глобальное пространство и оставить синхронный метод в потоке. Но при выходе закрывать или освобождать сокет из другого потока, а этому потоку назначить IsBackground (подробнее тут) чтобы даже при некорректном выходе поток не завис.