c# - 启动线程时的不同行为 : ParameterizedThreadStart vs. 匿名委托(delegate)。为什么这有关系?

标签 c# multithreading closures

当我运行下面的代码时,输​​出是“DelegateDisplayIt”,通常重复 1-4 次。我已经运行这段代码大概 100 次了,而且没有一次输出是“ParameterizedDisplayIt”。因此,线程创建和随后启动的方式似乎会影响参数的传递方式。当使用匿名委托(delegate)创建新线程时,参数是对原始变量的引用,但是当使用 ParameterizedThreadStart 委托(delegate)创建时,参数是一个全新的对象?我的假设是否正确?如果是这样,这似乎是线程构造函数的一个奇怪的副作用,不是吗?

static void Main()
{
    for (int i = 0; i < 10; i++)
    {
        bool flag = false;

        new Thread(delegate() { DelegateDisplayIt(flag); }).Start();

        var parameterizedThread = new Thread(ParameterizedDisplayIt);
        parameterizedThread.Start(flag);

        flag = true;
    }

    Console.ReadKey();
}

private static void DelegateDisplayIt(object flag)
{
    if ((bool)flag)
        Console.WriteLine("DelegateDisplayIt");
}

private static void ParameterizedDisplayIt(object flag)
{
    if ((bool)flag)
        Console.WriteLine("ParameterizedDisplayIt");
}

最佳答案

你的假设是正确的。语句 parameterizedThread.Start(flag) 在调用时复制标志变量。

相比之下,匿名委托(delegate)在 closure 中捕获原始变量.在委托(delegate)执行 DelegateDisplayIt 方法之前,不会复制变量。此时,该值可能为 true false,具体取决于原始线程在调用循环中的位置。

关于c# - 启动线程时的不同行为 : ParameterizedThreadStart vs. 匿名委托(delegate)。为什么这有关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1923577/

相关文章:

multithreading - 停止 Delphi Indy 线程而不必等待结束超时

javascript - 闭包中的 jquery tmpl

javascript - 如何阅读 Javascript 闭包语法?

c# - 返回查询结果的异步流

C pthread : Multiple Threads but only ONE thread is used

c# - 在 PowerShell 中,如何确定当前驱动器是否为网络驱动器?

java - 调用wait()、notify()或notifyAll()时如何获得相同的监视器?

scala - 为什么下面的 Scala 函数被称为闭包?

c# - 如何替换字节

c# - Sqlite-net guid select 返回空 guid