代码之家  ›  专栏  ›  技术社区  ›  JulianR

“不能在lambda表达式内使用固定的局部”

  •  5
  • JulianR  · 技术社区  · 14 年前

    不能在匿名方法、lambda表达式或查询表达式中使用固定的本地“depthPtr”

    depthPtr 是一个 fixed float* 一个数组,用于 Parallel.For System.Threading . 正如我所说的,它在VS2008上编译并运行得很好,但在VS2010上却不行,即使是针对.NET3.5。

    在.NET4.0中,这种情况发生了变化吗?即便如此,当我选择.NET3.5作为目标框架时,它是否仍应编译?在Google和Bing中搜索“cannotuseffixedlocal”只会得到一个(无用的)结果。

    fixed

    编辑:

    static unsafe void Main(string[] args)
    {
      float[] array = new float[10];
    
      fixed (float* ptr = array)
      {
        Parallel.For(0, 10, i =>
        {
          ptr[i] = i;
        });
      }
    }
    

    以上是在VS2008中编译的(除了引用 Parallel ,但任何其他lambda表达式都可以),但在VS2010中没有。

    5 回复  |  直到 11 年前
        1
  •  3
  •   Logan Capaldo    14 年前

    修复了在块期间锁定指针的问题。如果要存储在块退出后稍后调用的委托,垃圾收集器可以在创建lambda和调用lambda之间移动对象。至于为什么针对不同的框架没有帮助,这是因为这是由语言/编译器执行的,而不是由运行时执行的(如果是运行时,则会在运行时通过异常或类似情况报告,而不是由编译器在编译时报告)。

        2
  •  2
  •   Igor Zevaka    14 年前

    这很管用。基本上,我们消除了包含不安全指针的lambda,并将其替换为对在 fixed

        static unsafe void UnsafeTest(string[] args) {
            float[] array = new float[10];
    
            fixed(float* ptr = array) {
                UnsafeOps ops = new UnsafeOps();
                ops.p = ptr;
    
                Parallel.For(0, 10, ops.Lambda);
            }
        }
    
        unsafe class UnsafeOps {
            public float* p;
            public unsafe void Lambda(int value) {
                p[value] = value;
            }
        }
    

    UnsafeOps 固定的

        3
  •  1
  •   LukeN    14 年前

    这个 doco

        4
  •  1
  •   Ben Voigt    14 年前

    编译器拒绝该代码是正确的。Fixed只能用于局部变量,而闭包捕获的变量不是局部变量,它们被提升到类中用来维护闭包的状态。

        5
  •  0
  •   Femaref    14 年前