我的代码有问题,它可以正常工作, 但是在随机时间调用Marshal.Copy函数会使我获得访问冲突异常。 我的程序从X射线扫描仪获取图片。 X射线扫描仪将图像存储在内存中,并为我提供了从中获取该图片的指针。 我使用Marsharl.Copy将指针中的信息放入大小为2 * Width(x个像素的个数)* height(Y个像素的个数)的字节数组中并进行处理。
这是每1.5秒左右调用一次以获得图像的函数
public void GetLiveImage()
{
VirtCp.SLivePrms lp = new VirtCp.SLivePrms();
Mode mode = Modes.Where(x => x.ModeNumber == CurrentMode).First<Mode>();
MemoryError = false;
OkProceed = false;
int errCode = 0;
int timeout = 0;
xPixelSize = (int)mode.ColumnsPerFrame;
yPixelSize = (int)mode.LinesPerFrame;
imageSize = 2 * xPixelSize * yPixelSize;
IntPtr image = Marshal.AllocHGlobal(imageSize);
logger.WriteLine("Calling function to obtain image");
errCode = VirtCp.VipFluoroGetPrms(ref lp); // this function from the scanner dll gives points me to the data of the image
while (errCode != (int)HCPError.HCP_NO_ERR)
{
timeout++;
if (timeout > 350000)
{
logger.WriteLine("There are problems with detector:" + HCPErrorText.GetErrorText(errCode));
OkProceed = false;
return;
}
errCode = VirtCp.VipFluoroGetPrms(ref lp);
}
byteImage = new byte[imageSize];
try
{
if (errCode == (int)HCPError.HCP_NO_ERR)
{
logger.WriteLine("Transfering image byte data for processing");
Marshal.Copy(lp.BufPtr, byteImage, 0, imageSize); // this is the copy function that works 80% of the time, but at random it throws me into a memory access violation
logger.WriteLine("Saving raw and bmp images");
bool firstrun = true;
int BW_timeout = 0;
while ((ImageProcess_1.IsBusy && ImageProcess_2.IsBusy && ImageProcess_3.IsBusy) || firstrun)
{
firstrun = false;
BW_timeout++;
if (BW_timeout >= 300000)
{
logger.WriteLine("Errors trying to convert images");
OkProceed = false;
return;
}
if (!ImageProcess_1.IsBusy)
{
ImageProcess_1.RunWorkerAsync();
}
else if (!ImageProcess_2.IsBusy)
{
ImageProcess_2.RunWorkerAsync();
}
else if (!ImageProcess_3.IsBusy)
{
ImageProcess_3.RunWorkerAsync();
}
}
OkProceed = true;
}
else
{
logger.WriteLine("Error from detector function call: " + HCPErrorText.GetErrorText(errCode));
OkProceed = false;
logger.WriteLine("Will Try to obtain image again");
}
}
catch (Exception ex)
{
logger.WriteLine(ex.Message);
MemoryError = true;
}
try
{
Marshal.FreeHGlobal(image);
}
catch (Exception ex)
{
logger.WriteLine(ex.Message);
}
}
答案 0 :(得分:2)
取消引用指针需要两件事:
因此,如果遇到访问冲突,则只有三种可能性:
您处于这三种情况中的哪一种,我们不知道。
过去,当我不得不调试此类问题时,我对非托管堆进行了插桩,以记录分配和释放的详细信息,这样我就可以看到我处于这三种情况中的哪一种。祝你好运!