如何在C#中立即杀死一个线程?

时间:2009-08-25 09:24:01

标签: c# winforms multithreading

我使用thread.Abort方法来杀死线程,但它不起作用。有没有其他方法来终止线程?

private void button1_Click(object sender, EventArgs e)
{
    if (Receiver.IsAlive == true)
    {
        MessageBox.Show("Alive");
        Receiver.Abort();
    }
    else
    {
        MessageBox.Show("Dead");
        Receiver.Start();
    }
}

我正在使用此功能但每次获得Alive状态时,Receiver都是我的全局主题。

6 个答案:

答案 0 :(得分:67)

难以杀死一个线程的原因是因为语言设计者想要避免以下问题:你的线程会锁定,然后在它释放它之前杀掉它。现在任何需要锁定的人都会被卡住。

您需要做的是使用一些全局变量来告诉线程停止。您必须在线程代码中手动检查全局变量,如果看到它则返回,表明您应该停止。

答案 1 :(得分:32)

你可以通过这种方式立即杀死它:

private Thread _myThread = new Thread(SomeThreadMethod);

private void SomeThreadMethod()
{
   // do whatever you want
}

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
   _myThread.Abort();
}

我总是使用它并为我工作:)

答案 2 :(得分:20)

首先应该有一些商定的结束线程的方法。例如,线程可以检查并遵守的running_valiable。

您的主线程代码应该包含在一个异常块中,该异常块捕获ThreadInterruptException和ThreadAbortException,它将在退出时干净地整理线程。

在ThreadInterruptException的情况下,您可以检查running_变量以查看是否应该继续。在ThreadAbortException的情况下,你应该立即整理并退出线程程序。

尝试停止线程的代码应该执行以下操作:

running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
   threadInstance_.Abort();
}

答案 3 :(得分:7)

线程在完成它的工作时会被杀死,所以如果你正在使用循环或其他东西你应该将变量传递给线程以在线程完成之后停止循环。

答案 4 :(得分:5)

C#Thread.Abort不保证即时中止线程。当一个线程调用Abort本身而不是一个线程调用另一个线程时,它可能会工作。

请参阅文档:http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx

我在编写与硬件交互的工具时遇到了这个问题 - 您希望立即停止,但不能保证。我通常使用一些标志或其他这样的逻辑来阻止执行在线程上运行的代码部分(我不希望在中止时执行 - 棘手)。

答案 5 :(得分:-1)

    private void ResumeButton_Click(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            Application.Current.Resources["AutoPilotThreadStatus"] = true;
            Thread.CurrentThread.Name = "ResumeAutoPilot";
            Thread.CurrentThread.IsBackground = true;
            AutoPilotHandler.ResumeAutoPilot();
        });
    }

    public static void ResumeAutoPilot()
    {
        while ((bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            CheckAutoPilotThreadStatus();
            var searchYoutube = YoutubeHandler.Search("small truck");
            CheckAutoPilotThreadStatus();
            SaveVideosToDatabase(searchYoutube);
            CheckAutoPilotThreadStatus();
        }
    }

    public static void CheckAutoPilotThreadStatus()
    {
        if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"])
        {
            KillCurrentThread();
        }
    }

    public static void KillCurrentThread()
    {
        Thread.CurrentThread.Abort();
    }