#c# #memory #clock
#c# #память #часы
Вопрос:
У меня утечка памяти в этом проекте C #. Это аналоговые часы, и использование памяти увеличивается с каждой секундой. Какая ошибка была скрыта?
private void timer1_Tick(object sender, EventArgs e)
{
DateTime Now = DateTime.Now;
int Hour = Now.Hour;
int Minute = Now.Minute;
int Second = Now.Second;
Single AngleS = Second * 6;
Single AngleM = Minute * 6 AngleS / 60;
Single AngleH = Hour * 30 AngleM / 12;
backBox.Image = back;
backBox.Controls.Remove(backBox);
backBox.Controls.Add(hourBox);
hourBox.Location = new Point(0, 0);
hourBox.Image = rotateImage(hour, AngleH);
hourBox.Controls.Add(minuteBox);
minuteBox.Location = new Point(0, 0);
minuteBox.Image = rotateImage(minute, AngleM);
minuteBox.Controls.Add(dotBox);
dotBox.Location = new Point(0, 0);
dotBox.Image = dot;
dotBox.Controls.Add(secondBox);
secondBox.Location = new Point(0, 0);
secondBox.Image = rotateImage(second, AngleS);
}
Комментарии:
1. Вы продолжаете добавлять
Controls
. Это, вероятно, бесполезно и потребляет память.2. Покажите нам код для метода rotateImage().
Ответ №1:
System.Drawing.Image
объекты — это IDisposable
s, поэтому вам нужно позаботиться Dispose()
о любых повернутых изображениях, которые вы больше не используете.
В зависимости от вашего макета (который мы не видим из вашего фрагмента), может быть хорошей идеей провести рефакторинг, чтобы вы когда-либо рисовали повернутые объекты на одном изображении.
Ответ №2:
private void timer1_Tick(object sender, EventArgs e)
{
DateTime Now = DateTime.Now;
int Hour = Now.Hour;
int Minute = Now.Minute;
int Second = Now.Second;
Single AngleS = Second * 6;
Single AngleM = Minute * 6 AngleS / 60;
Single AngleH = Hour * 30 AngleM / 12;
// add this code
// i think
// backBox.Image.Dispose() is better but that can cause other errors
backBox.Image = null;
//
backBox.Image = back;
backBox.Controls.Remove(backBox);
backBox.Controls.Add(hourBox);
hourBox.Location = new Point(0, 0);
//add this code
hourBox.Image = null;
//
hourBox.Image = rotateImage(hour, AngleH);
hourBox.Controls.Add(minuteBox);
minuteBox.Location = new Point(0, 0);
// add this code
minuteBox.Image = null;
//
minuteBox.Image = rotateImage(minute, AngleM);
minuteBox.Controls.Add(dotBox);
dotBox.Location = new Point(0, 0);
// add this code
dotBox.Image = null;
//
dotBox.Image = dot;
dotBox.Controls.Add(secondBox);
secondBox.Location = new Point(0, 0);
// add this code
secondBox.Image = null;
//
secondBox.Image = rotateImage(second, AngleS);
}
Есть одна часть, которая меня беспокоит
private Bitmap rotateImage(Bitmap rotateMe, float angle)
{
Bitmap rotatedImage = new Bitmap(rotateMe.Width, rotateMe.Height);
using (Graphics g = Graphics.FromImage(rotatedImage))
{
g.TranslateTransform(rotateMe.Width / 2, rotateMe.Height / 2);
g.RotateTransform(angle);
g.TranslateTransform(-rotateMe.Width / 2, -rotateMe.Height / 2);
g.DrawImage(rotateMe, new Point(0, 0));
}
return rotatedImage;
}
minuteBox.Image = rotageedImage = rotateMe = минута
итак, если вы введете значение null, это может привести к сбою. Имейте это в виду!
Ответ №3:
Старый образ должен быть удален, поэтому
hourBox.Image = rotateImage(hour, AngleH);
Изменить на
var OldImage = hourBox.Image;
hourBox.Image = rotateImage(hour, AngleH);
if(OldImage != null )
{
OldImage.Dispose();
}
Проделайте то же самое с minute, dot и second .