Search code examples
c#imagegraphicsargumentexception

Graphics.ReleaseHdc() throws ArgumentException error with multi-threaded instances


I have a game with several enemies, each running in its own thread for movement and drawing. The enemies are drawn on a Panel and thus their threads have to access the Panel's Graphics. I have protected the CreateGraphics call using Lock and when I want to ReleaseHdc the Panel's Graphics I get a System.ArgumentException, even though I call the ReleaseHdc-method without any arguments. Here's the relevant code (p is the Panel reference passed down as a static variable and points to the correct control):

//Member region
internal Bitmap Img = new Bitmap(Image.FromFile(@"Enemy.png"), Size);
internal static readonly object _Lock = new object();

//from enemy's custom Move() method
lock (_Lock)
{
    Graphics gfx = p.CreateGraphics();
    gfx.DrawImage(Img, Location);
    gfx.ReleaseHdc(); // gfx.Dispose() works here                     
}

Does anyone have an idea why I get this error and/or how to fix it, considering the multi-thread access that I need to draw every element onto the same panel in its own thread?

[Edit]

Using gfx.Dispose() instead of ReleaseHdc() did the trick. The result though is not satisfying, because I get a very unstable image with flickering enemys. This is probably a problem from drawing them repeatedly often and not related to my question - or is there a connection between this problem and how I handle the multiple threads?


Solution

  • Shouldn't you be calling gfx.GetHdc() if you're going to call gfx.ReleaseHdc()?

    I think your code should look like this:

    lock (_Lock)
    {
        using (var gfx = p.CreateGraphics())
        {
            gfx.DrawImage(Img, Location);
        }
    }
    

    I also find the call to CreateGraphics() in itself is a little suspect. I'd expect the Graphics object to be supplied to the drawing code rather then created by it.