Main Site Documentation

TinyCLR - System.Drawing.Graphics Dispose Behaviour


#1

Hi John,

I’ve noticed that calling dispose on the Graphics object also seems to dispose the underlying image. Is this the correct behaviour?

Example:

            var displayController = DisplayController.GetDefault();

            displayController.ApplySettings(new ParallelDisplayControllerSettings
            {
                Width = 480,
                Height = 272,
                DataFormat = DisplayDataFormat.Rgb565,
                PixelClockRate = 20000000,
                PixelPolarity = false,
                OutputEnablePolarity = true,
                OutputEnableIsFixed = false,
                HorizontalFrontPorch = 2,
                HorizontalBackPorch = 2,
                HorizontalSyncPulseWidth = 41,
                HorizontalSyncPolarity = false,
                VerticalFrontPorch = 2,
                VerticalBackPorch = 2,
                VerticalSyncPulseWidth = 10,
                VerticalSyncPolarity = false,
            });

            var screen = Graphics.FromHdc(displayController.Hdc);

            var image = new Bitmap(100, 100);

            using (var graphics = Graphics.FromImage(image))
            {
                graphics.FillRectangle(new SolidBrush(Color.Green), 0,0,100,100);
            }

            screen.DrawImage(image,0,0); // Throws null reference exception

            screen.Flush();

#2

That is the current intended behavior, yes. Our goal is API compatibility so whether or not it’s correct depends on what the desktop .NET does. I wasn’t able to find any immediate confirmation one way or the other.


#3

Thanks,

If that’s the case then I think it’s wrong because the desktop version does not dispose the image:

Try running this on a standard windows form:

protected override void OnPaint(PaintEventArgs e)
{
	 var screen = this.CreateGraphics();

	var image = new Bitmap(100,100);

	using (var graphics = Graphics.FromImage(image))
	{
		graphics.FillRectangle(new SolidBrush(Color.Green), 0, 0, 100, 100);
	}

	screen.DrawImage(image, 0, 0);

	base.OnPaint(e);
 }

#4

That kind of makes sense to me because the image was created externally i wouldn’t expect the graphics object to control its lifetime. Also looking at the code for the graphics object in standard and corefx it looks like it creates and manages its own handle but the image is maintained separately.

https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Graphics.cs


#5

Thanks for the research! We’ll verify and update in a future release.


#6

Hi John,

I see that it now says its fixed in the 0.11 release - Great news!

From my point of view the two biggest things holding back System.Drawing at the moment are the absence of:

  1. Font.ComputeExt
  2. DrawTextInRect

Any idea on when we might see system.drawing.graphics equivalents?

public void DrawString(
string s,
Font font,
Brush brush,
RectangleF layoutRectangle
)

public SizeF MeasureString(
string text,
Font font,
SizeF layoutArea
)

Thanks,

David


#7

We are going through graphics this summer and the methods you mentioned are in our list.