You need to put all your networking code in a separate thread, not just connection. The idea is simple. You have to do so with any processing which takes time, especially with blocking calls such as most of networking operations.
You need to catch all exceptions at the top of stack of each thread, to prevent uncontrolled termination. At the same time you should not leave this code without any action. As a minimum, you need to log exception information or show it in UI. This rule have some exceptions for pretty rare cases. With networking, you may also need to do it in cycle, to recover from previous exceptions.
See more detail in my past answers:
How do i make a loop that will stop when a scrollbar reaches the bottom[
^],
When i run an application an exception is caught how to handle this?[
^],
throw . .then ... rethrowing[
^].
You're writing code in client side where you may need just one other thread. On server part you need to create at least two: one for listening for new connection and another one for reading/writing from/two network threads, communicating with clients using some application-level protocol.
You will find some more detail in my past answer here:
Multple clients from same port Number[
^].
Synchronization with other thread depends on your design. In particular, you may need to notify UI. You cannot call any UI methods from non-UI thread. Instead, you should use methods
Invoke
or
BeginInvoke
of
System.Windows.Threading.Dispatcher
or
System.Windows.Forms.Control
in all cases, including presenting exceptions. Please see detailed explanation of how it works and usage samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[
^],
Problem with Treeview Scanner And MD5[
^].
See also links to my past answers on threading:
How to get a keydown event to operate on a different thread in vb.net[
^],
Control events not firing after enable disable + multithreading[
^].
—SA