中止.NET线程

时间:2010-06-24 06:52:44

标签: c# .net

我正在创建一个线程A并在该线程中创建一个新线程B.

那么线程层次结构如何?线程B是线程A的子节点?或者将线程创建为对等体?

我想中止父线程A,后者又杀死/中止其子线程。

在C#中怎么可能?

5 个答案:

答案 0 :(得分:11)

理想情况下,永远不会中止线程。这根本不安全。将此视为一种解决已经生病的过程的方法。否则,就像瘟疫一样避免。

更正确的方法是让代码可以定期检查,本身决定退出。

答案 1 :(得分:6)

以礼貌的方式停止线程的一个例子:

using System;
using System.Threading;

namespace Treading
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main program starts");
            Thread firstThread = new Thread(A);
            ThreadStateMessage messageToA = new ThreadStateMessage(){YouShouldStopNow = false};
            firstThread.Start(messageToA);
            Thread.Sleep(50); //Let other threads do their thing for 0.05 seconds
            Console.WriteLine("Sending stop signal from main program!");
            messageToA.YouShouldStopNow = true;
            firstThread.Join();
            Console.WriteLine("Main program ends - press any key to exit");
            Console.Read();//
        }

        private class ThreadStateMessage
        {
            public bool YouShouldStopNow = false; //this assignment is not really needed, since default value is false
        }

        public static void A(object param)
        {
            ThreadStateMessage myMessage = (ThreadStateMessage)param;
            Console.WriteLine("Hello from A");
            ThreadStateMessage messageToB = new ThreadStateMessage();
            Thread secondThread = new Thread(B);
            secondThread.Start(messageToB);

            while (!myMessage.YouShouldStopNow)
            {
                Thread.Sleep(10);
                Console.WriteLine("A is still running");
            }

            Console.WriteLine("Sending stop signal from A!");
            messageToB.YouShouldStopNow = true;
            secondThread.Join();

            Console.WriteLine("Goodbye from A");
        }

        public static void B(object param)
        {
            ThreadStateMessage myMessage = (ThreadStateMessage)param;
            Console.WriteLine("Hello from B");
            while(!myMessage.YouShouldStopNow)
            {
                Thread.Sleep(10);
                Console.WriteLine("B is still running");
            }
            Console.WriteLine("Goodbye from B");
        }
    }
}

使用Thread.Abort();如果您的线程处于任何类型的等待状态,则会引发异常。这有点烦人,因为线程有很多种方式可以等待。正如其他人所说,你通常应该避免这样做。

答案 2 :(得分:4)

Thread.Abort会做你想要的,但不建议中止线程,更好的选择是通过Thread synchronization机制正确地思考完成线程的方法

答案 3 :(得分:3)

这是另一种礼貌地表示线程死亡的方式:

请注意,这种方式有利于有限状态自动机,其中从属设备定期检查生存权限,然后在允许的情况下执行任务。任务不会中断并且是“原子的”。这适用于简单的循环或命令队列。此外,这通过为从属线程提供休息时间来确保线程不会旋转100%cpu,如果您不希望在从属设备中休息,则将此设置为0。

var dieEvent = new AutoResetEvent(false);
int slaveRestPeriod = 20;// let's not hog the CPU with an endless loop
var master = new Thread(() =>
                            {
                                doStuffAMasterDoes(); // long running operation
                                dieEvent.Set(); // kill the slave
                            });

var slave = new Thread(() =>
                           {
                               while (!dieEvent.WaitOne(restPeriod))
                               {
                                   doStuffASlaveDoes();
                               }
                           });

slave.Start();
master.Start();

答案 4 :(得分:1)

线程创建为对等体,获取线程A的句柄,然后调用ThreadA.Abort() 强行结束它。最好检查线程中的布尔值,如果计算结果为false则退出线程。

public class MyClass
{
    public static Thread ThreadA;
    public static Thread ThreadB;

    private void RunThings()
    {
        ThreadA = new Thread(new ThreadStart(ThreadAWork));
        ThreadB = new Thread(new ThreadStart(ThreadBWork));

        ThreadA.Start();
        ThreadB.Start();
    }

    static void ThreadAWork()
    {
        // do some stuff

        // thread A will close now, all work is done.
    }


    static void ThreadBWork()
    {
        // do some stuff

        ThreadA.Abort(); // close thread A

        // thread B will close now, all work is done.
    }
}