简体   繁体   中英

Abort thread that is created locally in a method

The method below creates and starts a new thread for every client that is connected to TCP listener.

void StartClientCommuncationThread(TcpClient Client)
{
    Thread TcpClientThread = new Thread(new ParameterizedThreadStart(HandleClientCommTask));
    TcpClientThread.Start(Client);
}

I want to abort all threads when I pressed a button but I don't know how many threads were created and I could not reach the thread outside the method.

How can I abort the threads when I pressed a button?

Assuming you actually want to do an abort and not just end the thread, is there any reason you can't store the thread references in a collection and then call abort() on everyone?

The comments below are right. It would be better if you listened on a cancellation token to end a thread. However, sometimes you don't control certain threads, lets say something is unresponsive within the thread code because of a 3rd party library. This is a good time to call abort. Keep in mind that nothing will be cleaned up properly, your finally blocks may not execute, handles that need to be disposed of won't be disposed, etc. It's a pretty dirty job to call abort.

If you have access to the code running in the thread you should listen for cancellation tokens, or even just a shared (volatile) boolean value indicating that its time to bail out. If the thread has a long Thread.Sleep() in it then you should replace that with a mutex that you can pulse to wake the thread up and tell it to gracefully exit.

With reference to the IsBackground property on a thread. MSDN says

Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating.

So if you need to terminate the thread while your app is running setting this property won't do anything.

Here is an example illustrating the point

public class DisposeTest : IDisposable
{
    public void Run()
    {
        while (true)
        {
            Thread.Sleep(TimeSpan.FromDays(1));
        }

        Dispose();

    }
    public void Dispose()
    {
        Console.WriteLine("disposing");
    }
}

public class TestDriver
{
    static void Main(string[] args)
    {
        var diposeTest = new DisposeTest();

        var thread = new Thread(diposeTest.Run)
                            {
                                IsBackground = true
                            };
        thread.Start();

        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
}

In this app dispose never gets hit, even though the application didn't hang and exited without error. This is a bad idea because you can leave sockets open, files unclosed, sql queries unfinished, all sorts of stuff.

There are many ways to end a thread, just be mindful of how you end it because doing so with abort could cause side effects if you aren't careful.

What you could do is ensure that all your threads are set with IsBackground = true before getting started and then on the click of the button you can close the form from where all threads were spawn. http://msdn.microsoft.com/en-us/library/aa457093.aspx enter link description here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM