krw12572 krw12572 - 1 month ago 7
C# Question

How to prevent ExternalException which occurs on graphics object

I'm working on a project where control updates and new image is drawn on a panel after every 10 seconds. Following code clears that panel first. Then draws a border to it.

private void DrawRectangle(Color color)
{
using (var graphics = CreateGraphics())
using (var pen = new Pen(color))
{
graphics.Clear(Color.Black); //External exception is thrown here.
graphics.DrawRectangle(pen, 0, 0, Size.Width - 1, Size.Height - 1);
}
}


Normally everything works fine but if I lock windows(press Win + L) then after 10 seconds when
graphics.Clear(Color.Black)
statement is executed, application crashes.

According to MSDN page: The Clear method clears the state of the graphics object and should not be called when the graphics object cannot be updated. For example, if the Clear method is called on a secure desktop in a terminal server session, an ExternalException may occur, leaving the Graphics object in an inconsistent state.

What should I do to prevent this crash? Should I check if windows is locked or not? and will that be the only case where this crash will occur?

Update: Same problem occurs when Screen saver is activated.

Answer

If you call CreateGraphics() when windows is locked or screensaver is shown, the graphics object it returns is in Inconsistent state and can not be used to paint. If we use such graphics object, it throws ExternalException.

Best way to get rid of this problem is suggested by user Hans Passant. Instead of using CreateGraphics() method to create graphics object, use panel's paint event. Paint event handler contains eventargs which contains graphics object. This graphics object should be used to do painting.

The reason this works because, panel's paint event does not get called when windows is locked or screensaver is shown. So no inconsistent graphics object is used for painting.