0

在将 int 变量传递给诸如本例中的任务时,我经常会得到奇怪的结果:

List<List<object>> ListToProcess = new List<List<object>>();

// place some lists in list to process
foreach (var temp in Foo)
    ListToProcess.Add(temp);

foreach (var tempArray in ListToProcess)
{
    // initialize each list in ListToProcess                    
}

int numberOfChunks = ListToProcess.Count; 
Task[] tasks = new Task[numberOfChunks];
for (int counter = 0; counter < numberOfChunks; counter++)
{
    tasks[counter] = Task.Factory.StartNew(() =>
        {
            // counter is always = 5  why?   <---------------------------
            var t = ListToProcess[counter];                        
        });
}

我怎么解决这个问题?

4

4 回答 4

3

这称为闭包。您没有使用变量的值,而是使用了变量本身。当代码执行时,它使用执行时的值,而不是定义任务时的值。

要解决此问题,我相信您会执行以下操作:

for (int counter = 0; counter < numberOfChunks; counter++)
{
    int cur = counter;
    tasks[counter] = Task.Factory.StartNew(() =>
    {
        // counter is always = 5  why?   <---------------------------
        var t = ListToProcess[cur];                        
    });
}
于 2012-04-11T23:01:58.713 回答
1

无法保证何时访问 StartNew 的 Action 块中的“计数器”变量。可能发生的情况是所有 5 个值都循环通过,并创建了任务,然后安排任务运行。

当它们运行时,将执行以下操作:

var t = ListToProcess[counter];

但在这个阶段,计数已经等于 5。

也许你应该看看并行集合?

ListToProcess.AsParallel().ForAll(list => dosomething(list));

该地区还有许多其他选择。

于 2012-04-11T23:01:18.420 回答
0
    for (int counter = 0; counter < numberOfChunks; counter++)
    {
        var referenceVariable = new{val=counter};
        tasks[counter] = Task.Factory.StartNew(() =>
            {
                var t = ListToProcess[referenceVariable.val];                        
            });
    }
于 2012-04-11T23:02:13.407 回答
0

由于变量被捕获,您可以通过在每个循环中重新声明一个新变量来解决这个问题。

for (int counter = 0; counter < numberOfChunks; counter++)
{
    int localCounter = counter;
    tasks[localCounter] = Task.Factory.StartNew(() =>
        {
            // counter is always = 5  why?   <---------------------------
            var t = ListToProcess[localCounter];                        
        });
}
于 2012-04-11T23:02:14.810 回答