0

I know there are quite a few questions on this subject, but I've found none of them help me from where I'm at. I'm not too familiar with threading.

I'm creating a space invaders game, using a pull MVC architecture.

That is - the View is passed an instance of the game, and regularly calls the game's getMainSprite() method which and displays that.

Meanwhile the game operates on it's own timer, and regularly updates its own main sprite.

Stripped down code:

SpaceInvaders.cs (main game class);

    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);

    }

Now when it does the updateSprite/setPixel method it randomly throws me the 'InvalidOperationException - object is currently in use elsewhere' error.

Can you explain why it's doing this, and what the suggested way to resolve it is?

tereško
  • 58,060
  • 25
  • 98
  • 150
dwjohnston
  • 11,163
  • 32
  • 99
  • 194

1 Answers1

0

From a similar question: https://stackoverflow.com/a/1852451/1364848

There's a lock inside GDI+ that prevents two threads from accessing a bitmap at the same >time. This is not a blocking kind of lock, it is a "programmer did something wrong, I'll >throw an exception" kind of lock.

Your timers are on different threads and both are accessing the bitmap with SetPixel.

You can synchronize your access to the bitmap using lock http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

Community
  • 1
  • 1
Chips Ahoy
  • 56
  • 1