1

I'm building a C# Gui. Included in it is a Refresh event which gets called every second or so to refresh the screen.

private void RefreshEverySecond_Tick(object o, EventArgs a) 
{

   if (Condition1) 
   {
      QuickStatusTextBox.Text = "Condition 1";
      QuickStatusTextBox.Font = new Font(QuickStatusTextBox.Font, FontStyle.Bold); 
   } 
   else 
   {
      QuickStatusTextBox.Text = "Condition 2";
      QuickStatusTextBox.Font = new Font(QuickStatusTextBox.Font, FontStyle.Regular); 
   } 

} 

In researching the way to do this, I've seen answers like this which encourage this behavior:

Easiest way to change font and font size with visual C#

BUT I've also seen a lot of chatter saying I should be using "Using" for IDisposable objects which I gather Font is.

When should I use "using" blocks in C#?

And examples of using with fonts: http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Question: What is the right way to change a text box from Bold to Regular at periodic intervals? Does my method violate any rules or risk a memory leak or contention because I'm not using "using", and is there a "proper" way using Using? Remember this updates every second... so I'm likely keeping the Garbage collector busy but what other side effects are going to bite me?

Community
  • 1
  • 1
BarkerChippy
  • 111
  • 8
  • You can dispose the previous font before setting a new one. `Font f = QuickStatusTextBox.Font; QuickStatusTextBox.Font = new Font("Tahoma", 10, FontStyle.Bold); f.Dispose();` – L.B Dec 17 '13 at 21:07
  • Regarding your question about whether to dispose fonts or not: ["When to call Dispose"](http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx) claims you shouldn't dispose fonts, unless you run into problems. Disposing of fonts which are actually still used by controls might open just another can-o-worms. (Note that in the MSDN example you linked, the Font object is not "given away" to a control, so the example method keeps undisputed ownership about that font.) –  Dec 17 '13 at 21:10
  • I am not sure how many fonts you use, but why not store them in some static variables/static list, instead of reinstating them every time you call your font-related methods. That way you would not have to worry too much about font-related leaks. –  Dec 17 '13 at 21:12
  • 1
    The Font property setter already takes care of it, don't help. – Hans Passant Dec 17 '13 at 21:33
  • Oh yes, Hans, you are correct :) –  Dec 17 '13 at 22:15

1 Answers1

1

A Font object in Winforms .NET actually encapsulates two things: a description of a typeface, and a handle to a GDI object which represents that typeface. One of those things represents a limited resource (the GDI handle) and the other does not.

While it might have been possible to have controls use the GDI handles of fonts which are used to set their properties, built-in controls do not do so. Instead, the line myControl.Font = myFont; will cause myControl to capture a description of the typeface encapsulated by myFont and make its own Font object for internal use. The control will ensure that its internal-use Font object gets disposed when either the control is disposed or its myControl.Font is set to a different font, but the control will neither dispose myFont nor care about when or whether it is disposed. Interestingly, it won't care if myFont had been disposed even before the statement above executed. Assuming nothing else has written it, reading myControl.Font will return a reference to myFont rather than the control's internal font object; if myFont has been disposed, then myControl.Font will return a reference to a font object which has been disposed (but could still be used to set other controls' Font properties).

If one wishes to most accurately ensure the prompt cleanup of GDI font resources, any font objects which will be used only as "templates" and won't be used for actual drawing may be disposed as soon as they are created. I don't know whether that should be recommended as a pattern, since I can't find any official documentation of controls' Font behavior, but it seems wasteful to have font objects holding GDI resources that are never going to be used. It's too bad controls' Font property doesn't use some sort of documented FontDescription class which would encapsulate just the typeface description but not the GDI handle, since such a design would make things a lot clearer.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • So it sounds like what you're saying is I could actually do this: using (NewFont = new Font (QuickStatusTextBox.Font, (choose a forma)) { QuickStatusTextBox.Font = NewFont; ... } – BarkerChippy Dec 18 '13 at 18:13
  • @user2410814: You could. Indeed, on all versions of .NET I've seen, you could even set the `QuickStatusTextBox.Font` property *after* the `using` and it would still work. I really wish Microsoft would document this issue; I don't like to rely upon undocumented behavior, but I also don't like leaving resources dangling, and I don't know any other safe way of writing a method like `SetControlFont(Control ctl, Font newFont)` which won't risk either leaving an abandoned `Font` dangling or disposing a `Font` that someone else might be expecting to actually draw with. – supercat Dec 18 '13 at 18:23