C# 如何在闭包中捕获ref变量?

C# 如何在闭包中捕获ref变量?,c#,multithreading,interlocked,C#,Multithreading,Interlocked,我有这样的代码(简化): 计数器变量用于控制正在进行的事情的总数 在lambda中(以及在lambda之外),变量仅使用ref引用。编译器如何处理这些捕获?是否保证所有代理(如果有多个)都将获得对计数器的相同引用,而不是对“单个”复制变量的引用?我对它进行了测试,结果正如预期的那样,但我想确定一下 使用显式ref计数器进行联锁更改和读取是否安全 为什么Resharper会给出这个古怪的建议,将变量包装在一个元素数组中?如下所示:long[]counter={0L},Interlocked.Inc

我有这样的代码(简化):

计数器
变量用于控制正在进行的事情的总数

在lambda中(以及在lambda之外),变量仅使用
ref
引用。编译器如何处理这些捕获?是否保证所有代理(如果有多个)都将获得对
计数器的相同引用,而不是对“单个”复制变量的引用?我对它进行了测试,结果正如预期的那样,但我想确定一下

  • 使用显式
    ref计数器
    进行联锁更改和读取是否安全

  • 为什么Resharper会给出这个古怪的建议,将变量包装在一个元素数组中?如下所示:
    long[]counter={0L}
    Interlocked.Increment(ref counter[0])
    。当它帮助或修复某些东西时,您能提供一个用例吗

  • 附言:这个问题是由你提出的


    注意:我知道什么是闭包,以及它在常见情况下是如何工作的。在将问题标记为重复问题之前,阅读具体问题1和2。我没有在互联网上的多个“循环结束”问题中找到这些问题的答案,所以。

    @Servy我不同意重复的说法。这个问题专门寻找有关lambada中声明的参数
    ref
    如何表现不正确的信息。基本上,他想知道ReSharper建议将其更改为单元素数组的原因。链接副本在我通读的任何答案中都没有提到这一点。@ScottChamberlain问题是如何通过引用访问封闭变量,以及它是否有效。重复的答案正好是这个问题。它解释了为什么您能够通过引用访问变量,它是如何实现的,以及为什么这样做。这个问题希望它以实际的方式运行,而另一个问题不希望它以实际的方式运行,这一事实并不影响对它实际运行方式的解释。如果你知道闭包是如何工作的,并且闭包是在变量而不是值上关闭的,那么你为什么要求闭包会有一个变量值的副本,而不是变量本身,当所有关于这个主题的问题都明确地说(并解释为什么)闭包没有复制变量的值时?@Servy我不是这样理解的,我是这样理解的“对resharper关心的闭合变量使用
    ref
    的用例是什么?建议我将其改为单元素数组“,我想问题1是重复的,但问题2不是,我认为这是整个问题的要点。greatvovan我建议您删除问题1,并改写您的问题,以便更关注问题2。@ScottChamberlain问题是如何实现闭包,闭包是否导致生成变量的副本,以及是否因此,对闭包中的变量使用
    ref
    将导致引用所生成变量的副本,并想知道resharpers建议如何修复所感知的问题。
    long counter = 0L;
    
    var t = Task.Run(async () =>
    {
        Interlocked.Increment(ref counter); // Resharper: "Access to modified closure"
        await Task.Delay(500);               // some work
    });
    // ...
    t.Wait();
    // ...
    Interlocked.Decrement(ref counter);