C#:将数组分配给另一个数组:复制还是指针交换?

时间:2015-04-01 19:08:49

标签: c# arrays multithreading

很抱歉提出这个问题,我一直在谷歌搜索,但似乎出现的是克隆或复制方法的引用,而不是C#中我的问题的实际答案。

我有两个字节数组,它们由两个线程访问。

private byte[] buffer1 = new byte[size];
private byte[] buffer2 = new byte[size];

我的目标是在buffer1中写Thread1,获取互斥锁,切换指针并重复此过程。 Thread2会获取互斥锁并始终阅读buffer2

目标是Thread2快速运行,不受Thread1中发生的副本的影响。

我不清楚当我执行以下操作时会发生什么:

byte[] temp = buffer1;
buffer1 = buffer2;
buffer2 = temp;

指针是否已切换或buffer2的内容被复制到buffer1?这应该是一个简单的问题,但我似乎无法找到解决方案。 Thread1正在进行Marshal.Copy(),我不希望来电影响Thread2

2 个答案:

答案 0 :(得分:16)

赋值总是只将一个表达式的值复制到变量中(或调用属性/索引器设置器)。

在你的情况下,用这个:

buffer1 = buffer2;

... buffer2的值只是字节数组的引用。因此,在该分配之后(并且假设没有其他分配),对字节数组进行了更改" via"一个变量将可见"通过"另一个变量。

这不是特定于数组类型的 - 这是引用类型在整个.NET中的工作方式:

StringBuilder x = new StringBuilder();
StringBuilder y = x;
x.Append("Foo");
Console.WriteLine(y); // Foo

只是理解数组总是引用类型。

答案 1 :(得分:8)

Array clas是a reference type,因此没有副本,只有引用分配。使用Array.CopyTo方法将一个数组的内容复制到另一个数组。

此行为与C++不同,您可以在其中覆盖=运算符。在.NET中,您无法覆盖它,也无法在分配时复制某些集合的内容。

其他方面,您要做的reference assign是一个原子操作,因此您可以考虑在代码中使用lock-free算法来处理这部分代码。