我有有錯誤一些代碼「AccessViolationException是由用戶代碼未處理:嘗試讀取或寫入受保護的內存...」是否需要鎖定才能修復?
一個下調違規版本功能如下:
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i/columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
int spriteLeft = Math.Max(l.X, 0);
int spriteRight = Math.Min(l.X + ButtonImages.ImageSize.Width, canvasData.Width);
int spriteTop = Math.Max(l.Y, 0);
int spriteBottom = Math.Min(l.Y + ButtonImages.ImageSize.Height, canvasData.Height);
int spriteWidth = spriteRight - spriteLeft;
int spriteHeight = spriteBottom - spriteTop;
byte* canvasRowLeft = canvasDataScan0 + (spriteTop * canvasData.Stride) + spriteLeft * 4;
byte* spriteRowLeft =
(byte*)spriteData.Scan0.ToPointer() +
Math.Max((spriteTop - l.Y), 0) * spriteData.Stride +
Math.Max((spriteLeft - l.X), 0) * 4;
for (int y = 0; y < spriteHeight; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < spriteWidth; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3]/255 + spriteWalk[0]);
canvasWalk[1] = (byte)(canvasWalk[1] * spriteWalk[3]/255 + spriteWalk[1]);
canvasWalk[2] = (byte)(canvasWalk[2] * spriteWalk[3]/255 + spriteWalk[2]);
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
canvasWalk[0] = 0;
:當與替換
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3]/255 + spriteWalk[0]);
甚至:在線路中發生
錯誤
迭代變量y
和x
每次崩潰時都有不同的值,所以這讓我相信一個外部函數正在修改位圖。
如果這實際上是我的問題,是否有辦法阻止fastBackground
和Canvas
被外部修改?我以爲LockBits
是應該做的是...
如果這還不夠回答,這裏的多一些我已經試過: 我增加了行
if ((updatingFastBackground) || (Calculating)) return;
如果fastBackground
Canvas
或退出的OnPaint其他功能正在修改尺寸。
我能使用互斥來防止修改從在同一時間油漆中運行(因爲我認爲他們必須)的位圖fastBackground
和Canvas
的功能,但我寧願阻止他們的另一種方式爲畫布是公開的,我不想要求在課堂上傳遞互斥鎖。
每@usr的建議,這個進一步修剪版本不會失敗......必須是PTD錯誤。 (程序員太愚蠢),即算術錯誤
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i/columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
byte* canvasRowLeft = canvasDataScan0;
byte* spriteRowLeft = (byte*)spriteData.Scan0.ToPointer();
for (int y = 0; y < 145; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < 145; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = 0;
canvasWalk[1] = 0;
canvasWalk[2] = 0;
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
標題提到'fixed'是我懷疑我應該使用'fixed'在編輯位圖來鎖定一些內存的原因。 – AppFzx
我認爲它需要使用[fixed](http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx)作爲解決方案。在這種情況下,你必須將他們的聲明移到不安全的地方...... – rene
@rene會使'byte * canvasDataScan0'和'byte * fbgDataScan0'足夠或者會導致其他隱藏錯誤,因爲它不會使實際位圖得到修復? – AppFzx