有一个imageList,我在其中上传文件如下:
// LOAD PHOTO
// get all photos as file and save it in imageListPhoto
int vPhotoSize = 0;
int[] indexDataFacePhoto = new int[400800];
foreach (int i in usersData.readId)
{
// 1. if you already have a user photo with id equal to i, then =>
// 2. => use for listView
// 3. else download nessesary photo and =>
// 4. => use again
Device.DisableDevice(axFP_CLOCK, m_nMachineNum);
string pathToPhoto = photoDir + "\\" + i.ToString() + ".jpg";
// 1.
if (System.IO.File.Exists(pathToPhoto))
{
// 2.
this.imageListPhoto.Images.Add(Image.FromFile(pathToPhoto));
continue;
}
// 3.
IntPtr ptrIndexFacePhoto = Marshal.AllocHGlobal(indexDataFacePhoto.Length);
bool bRet = axFP_CLOCK.GetEnrollPhotoCS(m_nMachineNum, i, ref vPhotoSize, ptrIndexFacePhoto);
if (bRet)
{
byte[] mbytCurEnrollData = new byte[vPhotoSize];
Marshal.Copy(ptrIndexFacePhoto, mbytCurEnrollData, 0, vPhotoSize);
System.IO.File.WriteAllBytes(pathToPhoto, mbytCurEnrollData);
}
Marshal.FreeHGlobal(ptrIndexFacePhoto);
// 4.
this.imageListPhoto.Images.Add(Image.FromFile(pathToPhoto));
Device.EnableDevice(axFP_CLOCK, m_nMachineNum);
}
此 imageList 在 ListViewItem 中使用(如果您需要代码,请告诉我)。使用此代码每第二次调用表单后,以下任何操作都会清除内存:
其实问题是如何立即清除已使用的内存?我试图在关闭表单时删除包含文件的文件夹,但它发誓该文件已被另一个进程占用。Despose也没有帮助。这条线Marshal.FreeHGlobal(ptrIndexFacePhoto);也没有工作。
直接从文件创建图像时:
它拥有资源(文件)的句柄。
解决问题的常用方法如下:
在这里,持有手柄的原始图像立即被丢弃(可以包裹在 中
using)。因此文件被释放。并将图像的副本添加到 ImageList。它与文件无关。
已用内存!=已用内存。垃圾收集器会在它认为合适的时候释放内存,通常这不会在删除内存中的资源后立即发生,而是在一段时间后发生。在几兆字节的卷上,您根本不必担心这一点。但是可以优化代码,修复繁忙文件的问题。
为了避免不必要的非托管内存分配,
AllocHGlobal可以使用一次。为避免不必要的数组分配,您还可以在循环外创建一个缓冲区数组。现在它应该吃更少的内存。
那么,决定是否值得将所有这些都写入磁盘?