c# - lambda 表达式中不可能的值

标签 c# arrays concurrency lambda

谁能告诉我,这段代码怎么可能:

for (byte i = 0; i < someArray.Length; i++)
{
    pool.QueueTask(() =>
        {
            if (i > 0 && i < someArray.Length)
            {
                myFunction(i, someArray[i], ID);
            }
        });
}

落在 myFunctionIndexOutOfRangeException 调用的那一行,因为 i 变量的值等于 someArray.Length?我真的不明白...

注意:pool 是一个简单线程池的实例,有 2 个线程。

注意2:for循环中的类型byte是有意放置的,因为数组长度不能超过字节最大值(根据前面创建数组的逻辑),我需要变量i byte 类型。

最佳答案

您的代码在 i 上创建了一个闭包,每次执行时它都会变成 someArray.Length。您最终传递给 QueueTask()Action 保留 for 循环的状态,并在执行时使用 i 的值。这是表达同样问题的可编译代码示例,

static void Main(string[] args)
{
    var someArray = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    var fns = new List<Action>();

    for (int i = 0; i < someArray.Length; i++)
    {
        fns.Add(() => myFunction(i, someArray[i]));
    }

    foreach (var fn in fns) fn();
}

private static void myFunction(int i, int v)
{
    Console.WriteLine($"{v} at idx:{i}");
}

您可以通过在本地复制封闭的周围变量来打破这一点,它在 Action 创建时保留 i 的值。

static void Main(string[] args)
{
    var someArray = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    var fns = new List<Action>();

    for (int i = 0; i < someArray.Length; i++)
    {
        var local = i;
        fns.Add(() => myFunction(local, someArray[local]));
    }

    foreach (var fn in fns) fn();
}

private static void myFunction(int i, int v)
{
    Console.WriteLine($"{v} at idx:{i}");
}

相关阅读:http://csharpindepth.com/Articles/Chapter5/Closures.aspx

关于c# - lambda 表达式中不可能的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33722405/

相关文章:

arrays - 斯卡拉微风 : can you create a DenseMatrix of Int Array elements?

arrays - 如何从 NSUserDefaults swift 中保存和检索类对象?

java - java中如何在一个线程完成时结束其他线程的处理

c# - 如何使用 Windows Store C++ 在没有窗口句柄的情况下渲染路径几何

c# - 页面提交后,GET 方法在 POST 方法之前执行?

c# - Convert.ToDecimal(string) 和 Decimal.Parse(string) 之间的区别

arrays - Ruby:哈希数组 - 如何根据作为数组的哈希键删除重复项

c# - Activator.CreateInstance(t, 42, args) 找不到构造函数

java - Future.get 无法阻塞 forkjoinpool/workstealingpool 中的线程

mysql - NodeJS : Where to connect to the database in code?