views:

599

answers:

4

I've created a Client-Server application, and on the Server I want to have the oportunity to stop the server and then start it again. The problem is that I can't stop the Thread that listen for Tcp Connections.

How can I close a Thread in C#?

Thanks.

private void KeepServer(){
    while (this.connected)
    {
         tcpClient = tls.AcceptTcpClient();
         Connection newConnection = new Connection(tcpClient);
    }
}
+7  A: 

In general, you should "stop" threads by indicating that you want them to stop, and letting them do it. It's recommended that you don't use Thread.Abort except for emergency situations where you're shutting down the whole application. (Calling Thread.Abort on the currently executing thread is safer, but still generally icky. That's what ASP.NET does when you redirect, by the way.)

I have a page about stopping threads gracefully. You don't have to use that exact code, of course - but the pattern of setting a flag and testing it periodically is the main point.

Now, how that gets applied in your particular situation will depend on how you're listening for TCP connections. If you could post the code used by that thread, we may be able to adapt it appropriately.

Jon Skeet
+1 This is good advice - what are the disadvantages of calling Thread.Abort? Does it cause hanging threads or memory leaks?
0A0D
Thread.Abort raises a ThreadAbortException on the thread, wherever execution is currently at. If the thread is running code that isn't expecting an exception - it could result in a lot of weird behavior.
LBushkin
Worse, dealing with ThreadAbortException complicates resource cleanup and can result in either complicated/messy code or resource leaks. As Jon says, it's a good idea to avoid `Thread.Abort()`.
LBushkin
@Roboto: You don't know that the thread is at a safe place to abort, so it can leave your app in a "bad" state.
Jon Skeet
@Jon: I looked at your example. Looks good, but wouldn't your example do the same?
0A0D
What do you mean by "do the same"? The point is that the flag is only tested when the worker thread wants to do so, when it knows it would be safe to exit... the timing is under the worker thread's control, not the thread which is asking it to stop.
Jon Skeet
Your example stop the Thread. But now I have another problem. When a client connect to the server, a message "User is connected" appears. After the second start of the server the same message appear for 3 time. Why? I don't understand. (I think that 3 indicates that I've pressed "Start", "Stop" and again "Start"; if I will press again "Stop" and "Start" the message will appear for 5 times)
Emanuel
+1  A: 

Yor Question is a little general, but, I think that this may help you:

Threads in C#

I paste a portion:

Stopping a Thread

Normally, when a thread is started, it runs until finished. However, it is possible to stop a thread by calling the Abort() method. In our example, if we want to stop firstThread, you would add the following code.

Read more at Suite101: How to Create, Stop and Suspend Threads in C# | Suite101.com http://www.suite101.com/article.cfm/c%5Fsharp/96436#ixzz0ZsZRRjKx

Happy coding!

mRt
A: 

You should use a boolean or a condition to stop the Thread. You can than use a Property to change the "Flag" of this boolean and the loop of the Thread will end. This is a proper way to do it. Of course, you can use Abort() on the Thread but this is not recommended and will raise an Exception that you will need to handle.

Daok
A: 

possible from the outside Thread.Abort and there is a way to pause. but its an incorrect way to do it...

you should just end the code to kill, reach the last } . and for pausing you should use a Mutex. the manner of opporation should be, you order the object to pause, and after it finishes with the current request it gets halt by the mutex before the next one. or just steps out side of the while for "kill".

btw the MSDN has a nice article describing common threading scenarios

Hellfrost
Personally I prefer Monitor.Wait/Notify/NotifyAll for pausing...
Jon Skeet
i haven't programmed C# for sevral months now... meant Monitor... but anything that can stop the thread and be triggered from the outside will work.... but yes monitor is nicer :-)
Hellfrost