Не будет утечки памяти, но лучше выпускать объекты GDI +, когда это имеет смысл для вас.Их количество в операционной системе ограничено, поэтому вы можете вызвать проблемы с рендерингом в ваших и других приложениях.Следует также упомянуть, что объекты GDI + (шрифты и т. Д.) Не могут одновременно использоваться потоками 2+ (могут возникнуть некоторые трудные для воспроизведения исключения).Вас могут заинтересовать некоторые измерения фактического времени создания объектов GDI + в зависимости от возможных исключительных задержек блокировки.«преждевременная оптимизация - корень всего зла» © Дональд Кнут
На самом деле для меня работает кэширование некоторых объектов GDI +: за цикл рисования.Код клиента может выглядеть следующим образом:
class Visual
{
public void Draw()
{
using (new GraphicsPalette()) {
DrawHeader();
DrawFooter();
}
}
private void DrawHeader() {
var brush = GraphicsPalette.GetSolidBrush(Color.Green);
...
}
public void DrawFooter() {
using (new GraphicsPalette()) { // ensures palette existence; does nothing if there is a palette on the stack
var brush = GraphicsPalette.GetSolidBrush(Color.Green); // returns the same brush as in DrawHeader
...
}
}
}
Поэтому нам нужна GraphicsPalette, чтобы игнорировать вложенную конструкцию и возвращать ту же кисть для данного потока.Предлагаемое решение:
public class GraphicsPalette : IDisposable
{
[ThreadStatic]
private static GraphicsPalette _current = null;
private readonly Dictionary<Color, SolidBrush> _solidBrushes = new Dictionary<Color, SolidBrush>();
public GraphicsPalette()
{
if (_current == null)
_current = this;
}
public void Dispose()
{
if (_current == this)
_current = null;
foreach (var solidBrush in _solidBrushes.Values)
solidBrush.Dispose();
}
public static SolidBrush GetSolidBrush(Color color)
{
if (!_current._solidBrushes.ContainsKey(color))
_current._solidBrushes[color] = new SolidBrush(color);
return _current._solidBrushes[color];
}
}