我试图在应用程序中实现Langton的Ant算法。它有1个Button和1个PictureBox控件。这是代码:
int x = 100, y = 100;
int angle = 90;
private void button1_Click(object sender, EventArgs e)
{
Bitmap resultImage = new Bitmap(pictureBox1.Width, pictureBox1.Height, PixelFormat.Format24bppRgb);
for (int i = 0; i < resultImage.Height; i++)
{
for (int z = 0; z < resultImage.Width; z++)
{
resultImage.SetPixel(z, i, Color.White);
}
}
pictureBox1.Image = resultImage;
Thread t = new Thread(new ThreadStart(run));
t.Start();
}
public void run()
{
while (true)
{
lock (pictureBox1.Image)
{
//Exception takes place here.
Bitmap b = (Bitmap)pictureBox1.Image;
string name = b.GetPixel(x, y).Name;
if (b.GetPixel(x, y).Name == "ffffffff")
{
angle -= 90;
b.SetPixel(x, y, Color.Black);
}
else
{
angle += 90;
b.SetPixel(x, y, Color.White);
}
pictureBox1.Image = b;
x += (int)Math.Cos(angle * Math.PI / 180);
y += (int)Math.Sin(angle * Math.PI / 180);
}
Thread.Sleep(50);
}
}
在run()
方法中,Bitmap b = (Bitmap)pictureBox1.Image;
处始终存在异常,并显示InvalidOperatopnException:对象当前正在其他地方使用。我是否锁定图像并不重要。当我将间隔增加到250毫秒或以上时,不会发生例外
答案 0 :(得分:2)
两件事:
Bitmap
已经在使用的PictureBox
,而应该直接用新图片替换它,或者先使用Clone
方法,然后重新分配,不要忘记旧位图的Dispose
,如果有的话。试试这个:
private void ButtonClick() {
Thread thread = new Thread( this.BackgroundThread );
thread.Start(); // ideally, replace this with the .NET Task library
}
private void BackgroundThread() {
Bitmap bmp = new Bitmap( ... );
// do bitmap pixel-setting here
this.Invoke( () => {
Bitmap old = this.pictureBox1.Image as Bitmap;
this.pictureBox1.Image = bmp;
if( old != null ) {
old.Dispose();
}
} );
}
另外,避免GetPixel
和SetPixel
,它们非常慢。而是这样做:
BitmapData data = bmp.LockBits();
Byte[] buffer = new Byte[ ... ];
Marshal.Copy( data.Scan0, buffer, ... );
// Manipulate raw pixel data contained in buffer here
bmp.UnlockBits( data );