0

我正在使用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)。

在那之后,它开始再次加载它们,其中一些是多次......

4

1 回答 1

0

我认为您需要对输入源列表进行分组/拆分。

考虑使用此答案作为将 IEnumerable 拆分为 n 部分的方法。然后使用按钮获取下一个/最后一个部分,并将其设置为您的绑定源。

于 2013-04-07T02:00:50.620 回答