为什么我的线程不会停止?

时间:2012-10-25 16:42:13

标签: c# multithreading thread-abort

我有以下代码,我使用Thread对象作为构造函数参数启动ParameterizedThreadStart

static object obj = new object();

static void Main(string[] args)
{
    ParameterizedThreadStart start = (o) =>
    {
        ThreadTest(o);
    };

    var t = new Thread(() => start(obj));
    t.Name = "t";
    t.Start();

    Thread.Sleep(3000);
    obj = null;

    // Why the Thread (t) continue here??
    Console.ReadKey();
}


private static void ThreadTest(object o)
{
    while (o != null)
    {
        Console.WriteLine(Thread.CurrentThread.Name);
        Thread.Sleep(1000);
    }
}

我在obj方法中将null设置为ThreadTest后,参数o仍然是有效对象,为什么?
如何使用o将参数null设置为obj

I would prefer not to use Thread.Abort

4 个答案:

答案 0 :(得分:7)

因为在C#中,引用是按值传递的。

因此,在Main中更改obj以引用NULL将不会更改在ThreadTest中引用的对象。

相反,您应该保持两个方法引用同一个对象,并且只是更改对象的属性以表示线程应该退出。

答案 1 :(得分:5)

oThreadTest方法中的本地参数 分配obj字段不会影响该参数。

您可以通过删除所有参数并直接使用该字段来解决此问题。一旦你这样做,你的代码仍然会被破坏,因为该字段不易变。

答案 2 :(得分:3)

调用方法时,您传递了引用的值。这意味着对内部参考的任何更改都不会在外部看到,反之亦然。您可能希望直接在全局变量级别进行同步:

static volatile object obj = new object();

static void Main(string[] args)
{
    ThreadStart start = () =>
    {
        ThreadTest();
    };

    var t = new Thread(() => start());
    t.Name = "t";
    t.Start();

    Thread.Sleep(3000);
    obj = null;

    // Why the Thread (t) continue here??
    Console.ReadKey();
}


private static void ThreadTest()
{
    while (obj != null)
    {
        Console.WriteLine(Thread.CurrentThread.Name);
        Thread.Sleep(1000);
    }
}

还请注意对象上的volatile。这将确保读取该值的其他线程可以看到一个线程的更改。

答案 3 :(得分:0)

尝试使用布尔值来控制线程停止,如下所示:

static volatile bool runThread = true;

static void Main(string[] args)
{
    var t = new Thread(ThreadTest);
    t.Start();

    Thread.Sleep(3000);
    runThread = false;

    Console.ReadKey();
}


private static void ThreadTest()
{
    while (runThread)
    {
        Console.WriteLine(Thread.CurrentThread.Name);
        Thread.Sleep(1000);
    }
}