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

メソッドで設定objnullた後もThreadTest、引数oはまだ有効なオブジェクトですが、なぜですか?引数を使用
するように設定するにはどうすればよいですか?onullobj

Thread.Abortは使いたくない

4

4 に答える 4

7

C#では、参照は値で渡されるためです。

したがって、メインでobjを変更してNULLを参照するように変更しても、ThreadTestでoが参照するオブジェクトは変更されません。

代わりに、両方のメソッドが同じオブジェクトを参照し続けるようにし、オブジェクトのプロパティを変更して、スレッドが終了する必要があることを通知する必要があります。

于 2012-10-25T16:46:55.867 に答える
5

oメソッドのローカルパラメータThreadTestです。
フィールドを割り当ててobjも、そのパラメーターには影響しません。

これを修正するには、すべてのパラメーターを削除し、フィールドを直接使用します。これを行うと、フィールドは揮発性ではないため、コードは壊れたままになります。

于 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オブジェクトのにも注意してください。これにより、1つのスレッドによる変更が、値を読み取る他のスレッドに表示されるようになります。

于 2012-10-25T16:53:52.677 に答える
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);
    }
}
于 2012-10-25T16:47:04.117 に答える