繁体   English   中英

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

[英]Abort thread that is created locally in a method

下面的方法为连接到TCP侦听器的每个客户端创建并启动一个新线程。

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

我想在按下按钮时中止所有线程,但我不知道创建了多少线程,我无法到达方法之外的线程。

按下按钮后如何中止线程?

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

以下评论是对的。 如果您收听取消令牌以结束线程会更好。 但是,有时你不控制某些线程,因为第三方库,我们可以说在线程代码中没有响应。 这是打电话给中止的好时机。 请记住,没有任何东西可以正常清理,你的finally块可能无法执行,需要处理的句柄也不会被丢弃等等。调用abort是一件非常脏的工作。

如果你有权访问线程中运行的代码,你应该监听取消令牌,或者甚至只是一个共享(volatile)布尔值,表明它有时间纾困。 如果线程中有一个长的Thread.Sleep() ,那么你应该用一个互斥体替换它,你可以用脉冲来唤醒线程并告诉它优雅地退出。

参考线程上的IsBackground属性。 MSDN说

后台线程与前台线程相同,除了后台线程不会阻止进程终止。

因此,如果您需要在应用程序运行时终止该线程,则此属性将不会执行任何操作。

这是一个说明这一点的例子

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));
    }
}

在这个应用程序中,即使应用程序没有挂起并且没有错误退出,也不会被命中。 这是一个坏主意,因为你可以保持套接字打开,文件未关闭,sql查询未完成,各种各样的东西。

有很多方法可以结束一个线程,只要注意你如何结束它,因为如果你不小心这样做,中止可能会导致副作用。

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

暂无
暂无

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

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