Всякий раз, когда вы делаете длительное заблокированное ожидание (например, ожидание входящего соединения), используйте форму «Начало / Конец» метода. Затем используйте ManualResetEvent для представления условия «должен выйти». Затем заблокируйте AsyncWaitHandle и событие выхода. Это позволит вам завершить чисто.
Пример:
// exit is a ManualResetEvent
var asyncResult = socket.BeginAccept(null, null);
if(WaitHandle.WaitAny(new[] { exit, asyncResult.AsyncWaitHandle }) == 0)
return;
var connection = socket.EndAccept(asyncResult);
И в вашем основном методе, когда вы хотите выйти:
exit.Set();