简体   繁体   English

中止在方法中本地创建的线程

[英]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. 下面的方法为连接到TCP侦听器的每个客户端创建并启动一个新线程。

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? 假设你实际上想要中止并且不仅仅是结束线程,是否有任何理由你不能将线程引用存储在集合中然后对每个人调用abort()?

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. 请记住,没有任何东西可以正常清理,你的finally块可能无法执行,需要处理的句柄也不会被丢弃等等。调用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. 如果你有权访问线程中运行的代码,你应该监听取消令牌,或者甚至只是一个共享(volatile)布尔值,表明它有时间纾困。 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. 如果线程中有一个长的Thread.Sleep() ,那么你应该用一个互斥体替换它,你可以用脉冲来唤醒线程并告诉它优雅地退出。

With reference to the IsBackground property on a thread. 参考线程上的IsBackground属性。 MSDN says MSDN说

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. 这是一个坏主意,因为你可以保持套接字打开,文件未关闭,sql查询未完成,各种各样的东西。

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. 您可以做的是确保在开始之前使用IsBackground = true设置所有线程,然后在单击按钮时可以关闭所有线程所在的表单。 http://msdn.microsoft.com/en-us/library/aa457093.aspx enter link description here http://msdn.microsoft.com/en-us/library/aa457093.aspx 在此输入链接说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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