views:

86

answers:

3

What is the best way to finish a multi-threaded application in a clean way?
I am starting several socket connections from the main thread in seperate sockets and wait until the end of my business day in the main thread and use currently System.Environment.Exit(0) to terminate it.
This leads to an unhandled execption in one of the childs. Should I stop the threads from the list? I have been reluctant to implement any real stopping in the childs yet, thus I am wondering about the best practice. The sockets are all wrapped nicely with proper destructors for logging out and closing, but it still leads to errors.

+2  A: 

have a look at jon skeet's articles about multithreading:

http://www.yoda.arachsys.com/csharp/threads/

especially "Shutting down worker threads gracefully":

http://www.yoda.arachsys.com/csharp/threads/shutdown.shtml

stmax
Very very good resource. Also take a look at http://www.albahari.com/threading/ for getting a clear understanding of alot of threading concepts.
Digicoder
+1  A: 

For manualy created threads you should set IsBackground property to true. In this case (if all your threads except main one) would be background, you application gracefully closed after returning from Main(string[] arg) function.

P.S. All Thread pools threads are background.

Sergey Teplyakov
Making all your worker threads background threads may avoid any cries of death as the process exits, but it is hardly graceful. Background threads are terminated, even if they are in the middle of doing something, once all foreground threads have ended.
OldFart
I have implemented this and I will test it Monday.
weismat
Tested and worked like a charme.
weismat
I'd say that's bad practice. It works in some cases, in the others you'll lose important data.
stmax
A: 

Whenever you do a long blocked wait (such as waiting for an incoming connection) use the Begin/End form of the method. Then use a ManualResetEvent to represent the 'should exit' condition. Then block on the AsyncWaitHandle and the exit event. This will allow you to terminate cleanly.

Example:

// exit is a ManualResetEvent
var asyncResult = socket.BeginAccept(null, null);
if(WaitHandle.WaitAny(new[] { exit, asyncResult.AsyncWaitHandle }) == 0)
   return;
var connection = socket.EndAccept(asyncResult);

And in your main method when you want to quit:

exit.Set();
Robert Davis