Я пытался сделать это как с помощью GDI + / Invalidate, так и с помощью элемента управления Line Shape. В обоих случаях память выходит из-под контроля. Чтобы продемонстрировать, создайте приложение формы Windows с объектом таймера, который установлен на 100 мс и включен, и используйте следующий код:
Public Class Form1
Private Y As Integer
Private intDirection As Integer = 1
Private Sub timTest_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timTest.Tick
Me.Invalidate()
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim g As Graphics = Me.CreateGraphics
Dim myPen As New Pen(Color.Black)
myPen.Width = 1
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.DrawLine(myPen, 10, 10, 200, Y)
Y += intDirection
If Y > Me.Height - 20 Then intDirection = -1
If Y < 0 Then intDirection = 1
g.Dispose()
myPen.Dispose()
End Sub
End Class
Таким образом, приведенный выше код вызывает утечку памяти при перемещении строки. Я думаю, причина в том, что за кулисами создаются неуправляемые растровые изображения для рисования формы, которые не выпускаются, потому что на управляемой стороне это просто указатель.
Если я добавлю следующий код в начале функции рисования
Dim intAlloc As Integer = Me.Width * Me.Height * 16
GC.AddMemoryPressure(intAlloc)
и в конце функции я вызываю
GC.RemoveMemoryPressure(intAlloc)
Использование памяти немного увеличивается и немного уменьшается, но никогда не выходит из-под контроля. Кажется, AddMemoryPressure и RemoveMemoryPressure предупреждают GC о том, что он должен быть запущен. Есть ли лучший способ сделать это или это правильно? Приведенный выше код является просто упрощением для примера, чтобы добраться до корня проблемы, которую я имею в более крупном компоненте с несколькими движущимися строками. Также это лучший способ рассчитать правильное значение для размещения в AddMemoryPressure?