У меня есть приложение c # WinForms, которое использует несвязанные представления данных в нескольких разных местах. Я использую Performance Profiler для проверки утечек памяти, что приводит к тревожным результатам.
В одной конкретной форме у меня есть два несвязанных представления данных в определенной форме: одно со списком записей, а другое отображает изображения, связанные с записью, выбранной в первой. С сеткой изображений связаны два ползунка: один позволяет регулировать размер изображения, а другой - количество столбцов. С некоторыми записями связано несколько сотен изображений. Когда я выбираю другую запись, в результате чего отображается новый набор изображений, мой профиль памяти становится все хуже и хуже.
После выполнения Clear (), как мне распоряжаться используемой памятью, в частности памятью, связанной с изображениями, хранящимися в просмотре данных.
Вот пример кода, который я использую:
private void SetupImageGrid()
{
dgvImages.Rows.Clear();
dgvImages.Columns.Clear();
dgvImages.SuspendLayout();
for (int i = 1; i <= ImageColumns; i++)
{
DataGridViewTextBoxColumn captionCol = new DataGridViewTextBoxColumn();
captionCol.Resizable = DataGridViewTriState.NotSet;
captionCol.Width = 75;
captionCol.Visible = true;
captionCol.Name = string.Format("colCaption{0}", i);
captionCol.DefaultCellStyle.Font = new Font(dgvImages.DefaultCellStyle.Font, FontStyle.Bold);
dgvImages.Columns.Add(captionCol);
DataGridViewTextBoxColumn filenameCol = new DataGridViewTextBoxColumn();
filenameCol.Visible = false;
filenameCol.Name = string.Format("colFilename{0}", i);
dgvImages.Columns.Add(filenameCol);
DataGridViewImageColumn imageCol = new DataGridViewImageColumn();
imageCol.Width = ImageColumnWidth*30;
imageCol.ImageLayout = DataGridViewImageCellLayout.Stretch;
imageCol.Name = string.Format("colImage{0}", i);
dgvImages.Columns.Add(imageCol);
}
}
private void FillImageGrid(int ImageColumns)
{
SetupImageGrid();
string imageAddr = "{Image File or FLD file containing a list of images}";
string imageExt = "";
bool noImagesInFLD = false;
bool AtLeastOneImageFound = false;
if (imageAddr != "")
{
if (File.Exists(imageAddr))
{
imageExt = Path.GetExtension(imageAddr);
switch (imageExt)
{
case ".FLD":
clsFolder FLD = new clsFolder();
FLD.FolderName = imageAddr;
FLD.OpenFolder();
if (FLD.FolderItems.Count == 0)
{
noImagesInFLD = true;
}
break;
default:
break;
}
Image[] img = new Image[ImageColumns];
string[] caption = new string[ImageColumns];
string[] fname = new string[ImageColumns];
bool ArrayIsEmpty = true;
for (int i = 0; i <= ImageColumns - 1; i++)
{
img[i] = blankImage; //blankImage is a byte array with a blank image
caption[i] = "";
fname[i] = "";
}
int idx = 0;
int ctr = 0;
ImageCount = 0;
imagesDisplayed.Clear(); //Dictionary containing image file names
if (!noImagesInFLD)
{
switch (imageExt.ToUpper())
{
case ".FLD":
clsFolder FLD = new clsFolder();
FLD.FolderName = imageAddr;
FLD.OpenFolder();
for (int i = 1; i <= FLD.FolderItems.Count; i++)
{
FolderItem fi = FLD.FolderItems.get_Item(i);
idx = ctr % ImageColumns;
ctr++;
caption[idx] = string.Format("Image {0}", ctr);
if (File.Exists(fi.FolderLiteralPath))
{
AtLeastOneImageFound = true;
fname[idx] = fi.FolderLiteralPath;
img[idx] = Image.FromFile(fi.FolderLiteralPath);
ImageCount++;
imagesDisplayed.Add(ImageCount, fname[idx]);
}
else
{
img[idx] = Properties.Resources.missingimage;
}
ArrayIsEmpty = false;
if ((idx == ImageColumns - 1)) // || FirstTimeThrough)
{
dgvImages.Rows.Add();
for (int c = 0; c <= ImageColumns - 1; c++)
{
dgvImages[c * 3, dgvImages.Rows.Count - 1].Value = caption[c];
dgvImages[c * 3 + 1, dgvImages.Rows.Count - 1].Value = fname[c];
dgvImages[c * 3 + 2, dgvImages.Rows.Count - 1].Value = img[c];
}
dgvImages.Rows[dgvImages.Rows.Count - 1].Height = Convert.ToInt16((4.0 / 3.0) * dgvImages.Columns[2].Width);
for (int j = 0; j <= ImageColumns - 1; j++)
{
img[j] = blank;
caption[j] = "";
fname[j] = "";
}
ArrayIsEmpty = true;
}
}
if (!ArrayIsEmpty)
{
dgvImages.Rows.Add();
for (int c = 0; c <= ImageColumns - 1; c++)
{
dgvImages[c * 3, dgvImages.Rows.Count - 1].Value = caption[c];
dgvImages[c * 3 + 1, dgvImages.Rows.Count - 1].Value = fname[c];
dgvImages[c * 3 + 2, dgvImages.Rows.Count - 1].Value = img[c];
}
dgvImages.Rows[dgvImages.Rows.Count - 1].Height = Convert.ToInt16((4.0 / 3.0) * dgvImages.Columns[2].Width);
}
break;
case ".JPG":
case ".JPEG":
case ".PNG":
dgvImages.Rows.Add();
dgvImages[0, dgvImages.Rows.Count - 1].Value = "Image 1";
dgvImages[1, dgvImages.Rows.Count - 1].Value = imageAddr ;
dgvImages[2, dgvImages.Rows.Count - 1].Value = Image.FromFile(imageAddr);
for (int c = 1; c <= ImageColumns - 1; c++)
{
dgvImages[c * 3, dgvImages.Rows.Count - 1].Value = caption[c];
dgvImages[c * 3 + 1, dgvImages.Rows.Count - 1].Value = fname[c];
dgvImages[c * 3 + 2, dgvImages.Rows.Count - 1].Value = img[c];
}
dgvImages.Rows[dgvImages.Rows.Count - 1].Height = Convert.ToInt16((4.0 / 3.0) * dgvImages.Columns[2].Width);
break;
case ".TIF":
case ".TIFF":
//This is for handling multi-page TIFF files
Image im = Image.FromFile(imageAddr);
FrameDimension dimension = FrameDimension.Page;
int pageCount = im.GetFrameCount(dimension);
pBar.Maximum = pageCount;
ctr = 0;
for (int i = 0; i <= pageCount-1; i++)
{
idx = ctr % ImageColumns;
ctr++;
caption[idx] = string.Format("Image {0}", ctr);
fname[idx] = string.Format("FRAME{0}",i);
im.SelectActiveFrame(dimension, i);
img[idx] = new Bitmap(im);
ImageCount++;
imagesDisplayed.Add(ImageCount, fname[idx]);
ArrayIsEmpty = false;
if ((idx == ImageColumns - 1)) // || FirstTimeThrough)
{
dgvImages.Rows.Add();
for (int c = 0; c <= ImageColumns - 1; c++)
{
dgvImages[c * 3, dgvImages.Rows.Count - 1].Value = caption[c];
dgvImages[c * 3 + 1, dgvImages.Rows.Count - 1].Value = fname[c];
dgvImages[c * 3 + 2, dgvImages.Rows.Count - 1].Value = img[c];
}
dgvImages.Rows[dgvImages.Rows.Count - 1].Height = Convert.ToInt16((4.0 / 3.0) * dgvImages.Columns[2].Width);
for (int j = 0; j <= ImageColumns - 1; j++)
{
img[j] = blank;
caption[j] = "";
fname[j] = "";
}
ArrayIsEmpty = true;
}
}
if (!ArrayIsEmpty)
{
dgvImages.Rows.Add();
for (int c = 0; c <= ImageColumns - 1; c++)
{
dgvImages[c * 3, dgvImages.Rows.Count - 1].Value = caption[c];
dgvImages[c * 3 + 1, dgvImages.Rows.Count - 1].Value = fname[c];
dgvImages[c * 3 + 2, dgvImages.Rows.Count - 1].Value = img[c];
}
dgvImages.Rows[dgvImages.Rows.Count - 1].Height = Convert.ToInt16((4.0 / 3.0) * dgvImages.Columns[2].Width);
}
break;
default:
break;
} //switch (imageExt.ToUpper())
} //if (!noImagesInFLD)
} //if (File.Exists(imageAddr))
} //if (imageAddr != "")
dgvImages.ResumeLayout(true);
}