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);