Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#简单的多线程-为什么不能产生正确的结果?_C#_Multithreading - Fatal编程技术网

C#简单的多线程-为什么不能产生正确的结果?

C#简单的多线程-为什么不能产生正确的结果?,c#,multithreading,C#,Multithreading,有人能告诉我为什么下面的结果不正确吗?当我期待0123时,它给了我1233 public static readonly object locker = new object(); public static List<int> queue = new List<int>(); public static void calculate(int input) { Thread.Sleep(1000); loc

有人能告诉我为什么下面的结果不正确吗?当我期待0123时,它给了我1233

    public static readonly object locker = new object();
    public static List<int> queue = new List<int>();

    public static void calculate(int input)
    {
        Thread.Sleep(1000);
        lock (locker)
        {
            queue.Add(input);
        }
    }

    [TestMethod]
    public void TestT()
    {
        int[] _intList = new int[] { 0, 1, 2, 3 };
        List<Thread> _threadList = new List<Thread>();
        foreach (int num in _intList)
        {
            Thread t = new Thread(() => calculate(num));
            t.Start();
            _threadList.Add(t);
        }

        foreach (Thread t in _threadList) { t.Join(); }

        foreach (var t in queue)
        {
            Console.WriteLine(t);
        }
    }

将变量传递给lambda表达式时,它将被表达式捕获。所以这不是一个拷贝,而是你得到的变量。这是foreach和延迟执行(多线程或非多线程)的一个常见问题,因为foreach continues num正在获取它的下一个值,如果它这样做是因为线程要计算,那么将计算该值

如果您没有多线程,而是在foreach之后调用lambda的结果,您将看到的结果将是3,在这种情况下,您只是看到它们的集合为1,因为启动线程所需的时间很可能与1次迭代相同


在创建变量副本时,该变量在foreach的范围内声明,并且每次都是一个新变量,它不会被更改为下一个成员,而该变量就是被捕获的变量,为您提供了正确的结果。这是正确的方法。您得到的结果并非意外,但也不能保证,第一个方法可以得到0 1 2 3到3 3 3之间的任何结果,第二个方法保证正确的输出。

当您将变量传递给lambda表达式时,它会被表达式捕获。所以这不是一个拷贝,而是你得到的变量。这是foreach和延迟执行(多线程或非多线程)的一个常见问题,因为foreach continues num正在获取它的下一个值,如果它这样做是因为线程要计算,那么将计算该值

如果您没有多线程,而是在foreach之后调用lambda的结果,您将看到的结果将是3,在这种情况下,您只是看到它们的集合为1,因为启动线程所需的时间很可能与1次迭代相同


在创建变量副本时,该变量在foreach的范围内声明,并且每次都是一个新变量,它不会被更改为下一个成员,而该变量就是被捕获的变量,为您提供了正确的结果。这是正确的方法。您得到的结果并非意外,但也不能保证,第一个方法可以得到0 1 2 3到3 3 3之间的任何结果,第二个方法保证正确的输出。

当您将变量传递给lambda表达式时,它会被表达式捕获。所以这不是一个拷贝,而是你得到的变量。这是foreach和延迟执行(多线程或非多线程)的一个常见问题,因为foreach continues num正在获取它的下一个值,如果它这样做是因为线程要计算,那么将计算该值

如果您没有多线程,而是在foreach之后调用lambda的结果,您将看到的结果将是3,在这种情况下,您只是看到它们的集合为1,因为启动线程所需的时间很可能与1次迭代相同


在创建变量副本时,该变量在foreach的范围内声明,并且每次都是一个新变量,它不会被更改为下一个成员,而该变量就是被捕获的变量,为您提供了正确的结果。这是正确的方法。您得到的结果并非意外,但也不能保证,第一个方法可以得到0 1 2 3到3 3 3之间的任何结果,第二个方法保证正确的输出。

当您将变量传递给lambda表达式时,它会被表达式捕获。所以这不是一个拷贝,而是你得到的变量。这是foreach和延迟执行(多线程或非多线程)的一个常见问题,因为foreach continues num正在获取它的下一个值,如果它这样做是因为线程要计算,那么将计算该值

如果您没有多线程,而是在foreach之后调用lambda的结果,您将看到的结果将是3,在这种情况下,您只是看到它们的集合为1,因为启动线程所需的时间很可能与1次迭代相同


在创建变量副本时,该变量在foreach的范围内声明,并且每次都是一个新变量,它不会被更改为下一个成员,而该变量就是被捕获的变量,为您提供了正确的结果。这是正确的方法。您得到的结果并非意外,但也不能保证,第一种方法可以得到从0 1 2 3到3 3 3的任何结果,第二种方法保证正确的输出。

您编译的是哪个版本的c#?或者你为什么期望结果是0123?线程可以按任何顺序调度…@RonanThibaudau他们改变了foreach循环在5.0中编译的方式compiler@RonanThibaudau是的。你是针对哪个版本的c#编译的?或者你为什么期望结果是0123?线程可以按任何顺序调度…@RonanThibaudau他们改变了foreach循环在5.0中编译的方式compiler@RonanThibaudau是的。你是针对哪个版本的c#编译的?或者你为什么期望结果是0123?线程可以按任何顺序调度…@RonanThibaudau他们改变了foreach循环在5.0中编译的方式compiler@RonanThibaudau是的。你是针对哪个版本的c#编译的?或者你为什么期望结果是0123?线程可以按任何顺序调度…@RonanThibaudau他们改变了foreach循环在5.0中编译的方式compiler@RonanThibaudau赞成。
        foreach (int num in _intList)
        {
            int testNum = num;
            Thread t = new Thread(() => calculate(testNum));
            t.Start();
            _threadList.Add(t);
        }