我正在使用ObjectListView在 C# 中编写视频管理器,其中生成、保存预览图像,并将条目放入 sqlite db。从那里,我使用 VirtualObjectListView 组件在详细信息模式下显示条目(包括第一个图像作为预览)。
我遇到的问题是,有数百个条目,它开始吃掉内存,我看到很多文件(也有很多重复)在 Process Explorer 中打开/锁定。因此,我尝试实现一个缓存系统——一次只加载 30 张图像,在加载新图像时卸载不需要的图像。
它不起作用。它最终以某种方式加载每个文件的多个副本,只是感觉......哈克。在过去的几天里,我一直在寻找可以将方法绑定到的事件或其他东西,但我做不到,所以我不得不在AbstractVirtualListDataSource中使用GetNthObject。
无论如何,这是我的代码:
public override object GetNthObject(int n) {
VideoInfo p = (VideoInfo)this.Objects[n % this.Objects.Count];
p.ID = n;
int storeBufferHalf = 5;
int storeFrom = (n - storeBufferHalf < 0) ? 0 : n - storeBufferHalf;
int storeTo = (n + storeBufferHalf >= Objects.Count()) ? Objects.Count() - 1 : n + storeBufferHalf;
foreach (int cacheItem in cacheList.ToList()) {
if (cacheItem >= storeFrom && cacheItem <= storeTo)
continue;
VideoInfo unloadItem = (VideoInfo)this.Objects[cacheItem];
//Debug.WriteLine(cacheItem + " Preparing to delete cache: " + unloadItem.Name);
unloadItem.DestroyPreviewImage();
cacheList.Remove(cacheItem);
}
//Load up items into cache.
for (int i = storeFrom; i < storeTo; i++) {
if (!cacheList.Contains(i)) {
VideoInfo loadItem = (VideoInfo)this.Objects[i];
if (loadItem.PreviewImage != null)
continue;
loadItem.SetPreviewImage();
cacheList.Add(i);
}
}
return p;
}
更多信息:基本上,它有点工作......它确实加载了每个文件的多个副本,它最终确实加载了比你向下滚动一点后应该加载的更多图像(实际上是 60 个项目的整个测试数据库),但是向上和向下滚动列表几次可以卸载文件(至少根据 Process Explorer)。
在那之后,它开始再次加载它们,其中一些是多次......