3

我有以下代码,我开始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,参数仍然是一个有效的对象,为什么? 如何将参数设置为using ?nullThreadTesto
onullobj

我宁愿不使用 Thread.Abort

4

4 回答 4

7

Because in C#, references are passed by value.

So, changing obj to refer to NULL in Main will not change the object to which o refers in ThreadTest.

Instead, you should keep both methods referring to the same object, and just change a property of the object to signal that the thread should exit.

于 2012-10-25T16:46:55.867 回答
5

o is a local parameter in your ThreadTest method.
Assigning the obj field does not affect that parameter.

You can fix this by getting rid of all of the parameters and using the field directly. Once you do that, your code will still be broken, because the field is not volatile.

于 2012-10-25T16:45:36.357 回答
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对象上的 。这将确保读取该值的其他线程可以看到一个线程的更改。

于 2012-10-25T16:53:52.677 回答
0

Try using a Boolean to control the thread stop like so:

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);
    }
}
于 2012-10-25T16:47:04.117 回答