Clarification about System.Drawing.Font and Dispose
See original GitHub issue- Docs says nothing unusual here:
Call Dispose when you are finished using the Font. The Dispose method leaves the Font in an unusable state. After calling Dispose, you must release all references to the Font so the garbage collector can reclaim the memory that the Font was occupying.
-
Designer assigning fonts this way:
someControl.Font = new System.Drawing.Font(...);and never Dispose them. -
In .net Font.Dispose(bool disposing) has an
[SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")]attribute. But in core it’s gone. -
There are many questions about Font and Dispose on stackoverflow (with variants answers): Should I dispose of the old font when changing the font of a control? How and when is Font disposed for WinForms controls Calling dispose() for Font in Windows form Windows Form Fonts Questions Part 1 and more…
If nothing special here (docs are correct), why Designer never call Font.Dispose then? Otherwise, can we have official clarification (update docs)?
Ups, sorry about api-suggestion label - my bad 😦 Pls remove it.
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (11 by maintainers)

Top Related StackOverflow Question
Fonts are dangerous to dispose because they can be shared, if you want desterminstic disposal you need a thourough concept of ownership to be sure its safe to dispose. The designer certainly doesn’t have that. As far as I’m aware most of WinForms lets the GC clean up fonts, simply because its not safe to call Dispose when you don’t know who else is still using it.
A better design would have been making a shallow clone of the managed font class when assigning it to a form/control, reference counting how many managed references you have to a native font. Then you could have eager disposal without running the risk of releasing the native font too early.
However thats too late to do, as it actually would decrease “memory performance” since you would have a lot more manged font allocations just in order to support deterministic cleanup. (They’d share the same native font but still cost managed allocations.) Personally I don’t think its worth it, I never have seen a problem due to Fonts being cleaned up by GC too slow, I don’t think its a resource bottleneck.
As it stands the GC is the only safe place to release fonts, manual disposal of Fonts is only safe if you understand the whole program structure and are sure its not shared anymore at point of disposal.
PS: Bitmaps and Icons have the same problem. For Bitmaps it may actually be worth to implement a reference counting scheme and eager disposal, because lazy disposal by GC can keep files locked. Though I guess not high priority since most people have learned to work around file locking by making in-memory copies of the bitmap if waiting for file unlocking by GC is an issue.
As to WinForms usage @weltkante called out:
Yes, we’re stuck in WinForms as we don’t have any idea when people aren’t using them anymore as we expose them in public API.
There is confusion as
Fontdoesn’t disposeFontFamilywhich isIDisposable, but that hits the same case we generally have in WinForms (where System.Drawing originated). You can’t dispose it as it hangs publicly off ofFont.FontFamily.The docs wording is a little confusing as @RussKie points out. I presume it was called out for the above reasons.
In general I would say that it is best practice to null out any fields for objects you have disposed.
Fonthas a known, semi-documented need for it, but you should always do this as a matter of course to reduce rooting depth. That should hold true forFont- it should set theFontFamilyfield to null when it is disposed.So those are the action items I see:
Fontso it nulls out object fields on disposal (_fontFamily), which follows our own documented guidance, and perhaps makes explicitly calling it out moot