You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否保证变量值传递至新Task?代码断言是否始终成立?

问题解答

你的代码中,index和attributesChunked的变量值都能被正确传递到Task.Run的lambda表达式中,不过代码存在几处问题,修正后断言才能稳定通过,具体分析如下:

1. 变量捕获的作用域说明

  • index变量:它是在foreach循环的每次迭代内部声明的,每次迭代都会生成一个独立的index实例。lambda表达式捕获的是当前迭代的这个实例,不会被后续迭代的变量覆盖,因此每个Task拿到的都是当前迭代对应的index值,不会出现混乱。这里用Interlocked.Increment更新共享的chunkIndex是安全的,因为最终结果会被存入当前迭代的独立index变量中。
  • attributesChunked变量:在C# 5及以后的版本中,foreach的迭代变量是在每次迭代内部创建的新变量,而非共享同一个变量。因此每个Task的lambda捕获的都是当前迭代对应的chunk实例,不会出现多个Task共享同一个attributesChunked的问题。

2. 代码中的问题与修正

你的代码存在三处需要修正的地方:

  • 断言字符串错误:数组中第一个元素是"att1",但断言里写的是"attr1",不修正的话第一个断言会直接失败;
  • 逻辑错误:attributes.Chunk(2)会将4个元素分成2个chunk,index的值只会是0和1,因此index == 2的条件永远不会触发,第二个断言永远不会执行,应改为index == 1;
  • 语法错误:Task.Run的lambda表达式和tasks.Add的括号未闭合,无法编译。

修正后的代码如下:

var tasks = new List<Task>();
var attributes = new string[4]{ "att1", "att2", "att3", "att4" };
var chunkIndex = -1;
foreach (var attributesChunked in attributes.Chunk(2))
{
    var index = Interlocked.Increment(ref chunkIndex);
    tasks.Add(Task.Run(() =>
    {
        if (index == 0)
             Assert.Equal("att1", attributesChunked.First());
        if (index == 1)
             Assert.Equal("att3", attributesChunked.First());
    }));
}
await Task.WhenAll(tasks);

修正后,所有断言都能稳定通过,变量值的传递也完全符合预期。

内容的提问来源于stack exchange,提问作者Gary Brunton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:03:25