C# NET中任务和整数的意外行为

C# NET中任务和整数的意外行为,c#,.net,multithreading,task,value-type,C#,.net,Multithreading,Task,Value Type,我今天遇到了一个无法解释的问题。我有一个调用方法的任务,但是integer参数似乎没有被当作值类型来处理 我可以在一个简单的环境中复制它: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program {

我今天遇到了一个无法解释的问题。我有一个调用方法的任务,但是integer参数似乎没有被当作值类型来处理

我可以在一个简单的环境中复制它:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Start();
        }

        private static void Start()
        {
            int numberThreads = 3;

            for (int i = 0; i < numberThreads; i++)
            {
                if (i == 3)
                {
                    // Never gets hit
                    System.Diagnostics.Debugger.Break();
                }
                Task.Run(() => DoWork(i));
            }
        }

        private static void DoWork(int index)
        {
            if (index == 3)
            {
                // index = 3
                System.Diagnostics.Debugger.Break();
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
Start();
}
私有静态void Start()
{
int numberThreads=3;
对于(int i=0;iDoWork(i));
}
}
私有静态void DoWork(int索引)
{
如果(索引==3)
{
//指数=3
System.Diagnostics.Debugger.Break();
}
}
}
}
Start()中的(i==3)永远不会验证true,DoWork()中的(index==3)始终为true。
这怎么可能呢?

这是因为您在这里接受变量i
Task.Run(()=>DoWork(i)),但任务不会立即启动,并且FOR循环可以在该任务运行之前更改i。这就是为什么您可以在任务内部处理i==3

for (int i = 0; i < numberThreads; i++)
{
    if (i == 3)
    {
         // Never gets hit
         System.Diagnostics.Debugger.Break();
    }
    Task.Run(() => DoWork(i)); <= action will executed after we exited from for loop
}
for(int i=0;iTask.Run(()=>DoWork(i));这是因为您在这里接受变量i
Task.Run(()=>DoWork(i));
,但任务不会立即启动,FOR循环可以在任务运行之前更改i。这就是为什么您可以在任务内部处理i==3

for (int i = 0; i < numberThreads; i++)
{
    if (i == 3)
    {
         // Never gets hit
         System.Diagnostics.Debugger.Break();
    }
    Task.Run(() => DoWork(i)); <= action will executed after we exited from for loop
}
for(int i=0;iTask.Run(()=>DoWork(i));你想知道为什么你的
如果(i==3)
没有被命中吗?这是因为for循环从0开始。将其更改为
for(int i=1;i
并且它应该会命中你的if语句。不会有帮助的——你还必须更改
@James的条件,是的,这是一件奇怪的事情。我不希望在传递给
任务的委托中发生这种情况。运行
你正在关闭变量
I
,而不是循环中的当前值。你需要复制该值,例如。
int j=i;Task.Run(()=>DoWork(j))
。你想知道如果(i==3)
没有命中你的
吗?这是因为for循环从0开始。将其更改为
for(int i=1;i
并且它应该会命中你的if语句。不会有帮助的——你还必须更改
@James的条件,是的,这是一件奇怪的事情。我不希望在传递给
任务的委托中发生这种情况。运行
你正在关闭变量
I
,而不是循环中的当前值。你需要复制该值,例如。
intj=i;Task.Run(()=>DoWork(j))
。查看此答案需要更多描述或实际问题的大纲。它基本上是OP代码的复制粘贴。@ColinM我试图解释OP代码,所以我必须复制它。此答案需要更多描述或实际问题的大纲。它基本上是OP代码的复制粘贴。@ColinM我试图解释OP代码,所以我必须复制它把它打开。