在lambda表达式中引用的“安全”解除局部变量的规则是什么?

鲍勃·海

下面的示例在throw语句处引发IndexOutOfRangeException,因为该变量i超出了其限制(例如,当循环覆盖0和1时为2)。我期望这段代码可以创建lambda块0和1,它们分别将结果存储在相应的数组元素中。从设置断点开始,我注意到直到我调用,异步任务才真正开始执行Task.WaitAll()从《C#编程指南》中,我了解到,在i退出循环之后,编译器会竭尽全力保持作用域。

所以,我的问题是:

  1. 有人可以建议一种方法来实现我尝试创建的效果,即每个异步任务都应将其结果存储在数组中的不同插槽中?Task.Run()没有提供参数的重载(我将用它来传递i循环),并且lambda块声明无论如何都会阻止我尝试声明参数。

  2. 有人可以提供一个理由,为什么lambda表达式超出其声明块的作用域后才能够继续引用该局部变量是一种理想的行为吗?C#语言参考改变了“本地”声明的含义,以覆盖匿名函数和lambda块的提升,但这仅打开了获取意外值的门,如我的示例所示。

这是示例:

using System;
using System.Threading.Tasks;

namespace AsyncLifting
{
    class Program
    {
        static void Main(string[] args)
        {
            const int numTasks = 2;
            double[] taskResult = new double[numTasks];
            Task<int>[] taskHandles = new Task<int>[numTasks];

            for (int i = 0; i < numTasks; i++)
            {
                taskHandles[i] = Task.Run(async () =>
                {
                    DateTime startTime = DateTime.UtcNow;
                    await Task.Delay(10);
                    try
                    {
                        taskResult[i] = (DateTime.UtcNow - startTime).TotalMilliseconds;
                    }
                    catch (Exception e) { 
                        throw e;  // IndexOutOfRange, i is 2
                    }
                    return i;
                });
            }

            Task.WaitAll(taskHandles);

            Console.WriteLine("Task waits:");
            foreach (double tr in taskResult)
            {
                Console.WriteLine("  {0}ms.", tr);
            }
        }
    }
}
腐烂

委托正在关闭变量-它不仅在那时捕获值,而且还捕获整个变量这有时可能有用。

无论如何,为防止意外行为,只需创建一个新变量并在块内使用它:

for(int i = 0; i < n; i++) {
    int index = i;
    DoSomething(delegate() {
        myArray[index] = /* something */;
    });
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#编译器用来解析lambda表达式中的类型的规则是什么?

来自分类Dev

从lambda表达式引用的局部变量必须是final或有效的final

来自分类Dev

Lambda表达式如何共享局部变量?

来自分类Dev

在lambda表达式内分配局部变量

来自分类Dev

Lambda表达式捕获的局部变量?

来自分类Dev

在迭代 HashMap 时引用局部变量 -> 从 lambda 表达式引用的局部变量必须是最终的或有效的最终错误

来自分类Dev

如何在此C ++ lambda表达式中采用局部变量?

来自分类Dev

在rdlc表达式中设置局部变量

来自分类Dev

bash:在for表达式中声明局部变量

来自分类Dev

正则表达式的(f)lex规则是什么?

来自分类Dev

JS中的变量在循环中引用相同数据的规则是什么?

来自分类Dev

我如何从表达式树中访问局部变量的值

来自分类Dev

未在表达式eval中定义的Julia局部变量

来自分类Dev

什么时候可以解析C ++ 11 lambda表达式中的变量引用?

来自分类Dev

lambda表达式中变量名的约定是什么?

来自分类Dev

在OrderBy中lambda表达式的意义是什么?

来自分类Dev

在Python中,为什么lambda表达式可以引用要定义的变量,但不能引用列表?

来自分类Dev

使用C ++ lambda,按引用捕获引用的规则是什么?

来自分类Dev

变量:表达式在 Python 中是什么意思?

来自分类Dev

“ lambda表达式”的优点是什么?

来自分类Dev

销毁函数中的局部变量是什么意思

来自分类Dev

buf(主函数中的局部变量)的地址是什么?

来自分类Dev

张量流中的局部变量是什么?

来自分类Dev

javascript 中语句头的局部变量的范围是什么?

来自分类Dev

打破lambda表达式箭头的TsLint规则名称是什么?

来自分类Dev

什么是“分配前引用的局部变量”

来自分类Dev

Haskell 中的命名规则是什么?

来自分类Dev

确切地说,Chrome DevTools的“急切评估”预览文本将显示哪些表达式结果的一般规则是什么?

来自分类Dev

引用局部变量

Related 相关文章

  1. 1

    C#编译器用来解析lambda表达式中的类型的规则是什么?

  2. 2

    从lambda表达式引用的局部变量必须是final或有效的final

  3. 3

    Lambda表达式如何共享局部变量?

  4. 4

    在lambda表达式内分配局部变量

  5. 5

    Lambda表达式捕获的局部变量?

  6. 6

    在迭代 HashMap 时引用局部变量 -> 从 lambda 表达式引用的局部变量必须是最终的或有效的最终错误

  7. 7

    如何在此C ++ lambda表达式中采用局部变量?

  8. 8

    在rdlc表达式中设置局部变量

  9. 9

    bash:在for表达式中声明局部变量

  10. 10

    正则表达式的(f)lex规则是什么?

  11. 11

    JS中的变量在循环中引用相同数据的规则是什么?

  12. 12

    我如何从表达式树中访问局部变量的值

  13. 13

    未在表达式eval中定义的Julia局部变量

  14. 14

    什么时候可以解析C ++ 11 lambda表达式中的变量引用?

  15. 15

    lambda表达式中变量名的约定是什么?

  16. 16

    在OrderBy中lambda表达式的意义是什么?

  17. 17

    在Python中,为什么lambda表达式可以引用要定义的变量,但不能引用列表?

  18. 18

    使用C ++ lambda,按引用捕获引用的规则是什么?

  19. 19

    变量:表达式在 Python 中是什么意思?

  20. 20

    “ lambda表达式”的优点是什么?

  21. 21

    销毁函数中的局部变量是什么意思

  22. 22

    buf(主函数中的局部变量)的地址是什么?

  23. 23

    张量流中的局部变量是什么?

  24. 24

    javascript 中语句头的局部变量的范围是什么?

  25. 25

    打破lambda表达式箭头的TsLint规则名称是什么?

  26. 26

    什么是“分配前引用的局部变量”

  27. 27

    Haskell 中的命名规则是什么?

  28. 28

    确切地说,Chrome DevTools的“急切评估”预览文本将显示哪些表达式结果的一般规则是什么?

  29. 29

    引用局部变量

热门标签

归档