使用Buffer.BlockCopy C#发生奇怪的数据损坏

时间:2015-02-05 12:28:54

标签: c# arrays

背景

我正在编写一个C#程序,它通过数据采集收集一些信息。它非常复杂,所以我在这里没有详细说明,但数据采集是连续发起的,然后,在异步线程上,我的程序定期访问采集缓冲区并从中获取100个样本。然后我查看100个样本中的触发条件我感兴趣。如果我看到触发条件,我从预触发缓冲区收集一堆样本,更多来自后触发缓冲区,并将它们全部汇总一起组成一个200元素阵列。

在我的异步线程中,我使用Buffer.BlockCopy方法组装了我的200元素数组(double类型)。我选择使用这种方法的唯一具体原因是我需要注意我在异步线程中做了多少数据处理;如果我做得太多,我最终可能会过度填充采集缓冲区,因为我不经常访问它。由于Buffer.BlockCopy在将数据从源数组推送到目标数组方面比使用大型for循环更有效,这是我决定使用它的唯一原因。

问题

当我调用Buffer.BlockCopy方法时,我这样做:

Buffer.BlockCopy(newData, 0, myPulse, numSamplesfromPreTrigBuf, (trigLocation * sizeof(double));

其中;

newData 是一个double []数组,包含新数据(100个元素)(典型数据如0.0034,6.4342等,范围从0到7)。

myPulse 是目标数组。它实例化了200个元素。

numSamplesfromPreTrigBuf 是我要在此特定副本中应用的偏移量

trigLocation 是我要在此特定实例中复制的元素数。

复制没有错误,但写入myPulse的数据全部搞砸了;数字如-2.05E-289和5.72E + 250。无论是微小数字还是大数字。这些数字不会出现在我的源数组中。

我已经简单地通过使用Array.Copy()解决了这个问题,没有其他源代码修改,除了通过乘以sizeof(double)来消除计算要复制的元素数量的需要。但我确实花了两个小时尝试调试Buffer.BlockCopy()方法,完全不知道为什么副本是垃圾。

从我的Buffer.BlockCopy(我相信这是正确的用法)的示例用法,任何机构都有一个想法,垃圾数据如何被复制?

1 个答案:

答案 0 :(得分:5)

我认为你的偏移是错误的 - 它也是一个字节偏移量,所以你需要将它乘以sizeof(double),就像长度一样。

使用BlockCopy和类似的方法时要小心 - 你会失去一些.NET的安全性。与彻头彻尾的unsafe方法不同,它确实检查数组边界,但你仍然可以产生一些非常奇怪的结果(,我认为你可能会产生无效的引用 - 一个大问题 EDIT < / strong>:幸运的是,BlockCopy仅适用于基本类型数组。)

此外,BlockCopy不是线程安全的,因此如果您一次从多个线程访问共享缓冲区,则需要同步对共享缓冲区的访问。