我知道关于这个问题有很多问题,但我发现它们都没有帮助我从我所处的地方。我对线程不太熟悉。
我使用拉式MVC架构创建了一个太空入侵者游戏。
即 - 视图传递给游戏的一个实例,并定期调用游戏的getMainSprite()
方法并显示该方法。
同时游戏依靠自己的计时器运行,并定期更新自己的主精灵。
剥离代码:
SpaceInvaders.cs(主游戏类);
private void timerTick(object source, ElapsedEventArgs e)
{
mainSprite.updateWithSprite(0, 0, anim); //Anim is an animated sprite which we're displaying for now
}
Sprite.cs:
//*When we want to update a sprite, we pass in the sprite we want to update it with
and it updates all the pixels*/
public void updateWithSprite(int x, int y, Sprite sprite)
{
Bitmap sprBitmap = sprite.getBitmap();
for (int i = 0; i < sprBitmap.Width; i++)
{
for (int j = 0; j < sprBitmap.Height; j++)
{
this.bitmap.SetPixel(x + i, y + j, sprBitmap.GetPixel(i, j));
}
}
}
Form1.cs的
private void timerTick(object source, EventArgs e)
{
this.refreshView(this.game.getMainSprite());
}
private void refreshView(Sprite gs)
{
this.currentSprite = gs;
this.panel1.Refresh();
}
private void drawSprite(Graphics canvas, Sprite sprite){
Bitmap bitmap = (Bitmap)sprite.getBitmap();
//lock(bitmap)
canvas.DrawImage(bitmap, new Rectangle(0, 0, MAIN_SPRITE_WIDTH*PIXEL_WIDTH, MAIN_SPRITE_HEIGHT*PIXEL_WIDTH));
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
this.drawSprite(canvas, currentSprite);
}
现在当它执行updateSprite / setPixel方法时,它会随机抛出&#39; InvalidOperationException - 当前正在其他地方使用对象&#39;错误。
你能解释一下它为什么这样做,以及解决它的建议方法是什么?
答案 0 :(得分:0)
来自类似的问题:https://stackoverflow.com/a/1852451/1364848
GDI +中存在一个锁定,阻止两个线程在同一&gt;时间访问位图。这不是一种阻塞的锁,它是一个&#34;程序员做错了什么,我会抛出异常&#34;锁定。
您的计时器位于不同的线程上,并且都使用SetPixel访问位图。
您可以使用锁定http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
来同步对位图的访问权限