I’m calling tcpListener.AcceptTcpClient() inside its own thread. Because this blocks forever, the thread doesn’t exit when my form closes. I tried calling listenThread.Abort(), but the thread doesn’t exit. It’s stuck on AcceptTcpClient().
How can I get my whole program to shutdown when I close the main form?
Two separate problems:
How to stop a thread blocking app exit (dealt with in other answers)
How to unblock blocked Socket method calls (thereby making your code a little more reusable when you’re faced with wanting to stop accepting clients but keep the app running)
To allow the thread to exit gracefully, you can call Dispose on the listening socket:
which will cause all blocked operations to fail with a SocketException. Catch this, deal with it and allow the thread to terminate.