Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更好地实现WPF控制缓存?_C#_Caching_Collections_Controls_Garbage - Fatal编程技术网

C# 如何更好地实现WPF控制缓存?

C# 如何更好地实现WPF控制缓存?,c#,caching,collections,controls,garbage,C#,Caching,Collections,Controls,Garbage,我的同事发现,如果我们缓存WPF控件,而不是从头开始创建新的WPF控件,我们通常可以在WPF应用程序中获得性能改进。当然,通常使用更多内存会导致其他地方的性能下降,这很难衡量,但我们认为这仍然是值得的,因为与我们的应用程序处理的其他事情相比,这些控件占用的空间微不足道 下面是控件缓存的一种简单形式: public static class ControlCache<T> where T : Visual, new() { private static Dictionary&l

我的同事发现,如果我们缓存WPF控件,而不是从头开始创建新的WPF控件,我们通常可以在WPF应用程序中获得性能改进。当然,通常使用更多内存会导致其他地方的性能下降,这很难衡量,但我们认为这仍然是值得的,因为与我们的应用程序处理的其他事情相比,这些控件占用的空间微不足道

下面是控件缓存的一种简单形式:

public static class ControlCache<T> where T : Visual, new()
{
    private static Dictionary<T, bool> m_Cache = new Dictionary<T, bool>();

    public static T GetInstance()
    {
        if (m_Cache.Count == 0)
            return new T();
        else
        {
            var inst = m_Cache.First();
            m_Cache.Remove(inst.Key);
            return inst.Key;
        }
    }

    static int MAX_COUNT = 300;

    public static void Release(T ctrl)
    {
        if (ctrl != null && m_Cache.Count < MAX_COUNT && !m_Cache.ContainsKey(ctrl))
            m_Cache[ctrl] = true;
    }
}
缓存控件的主要缺点之一是需要在完成时显式释放它们。有时候,你真的需要做一些非常尴尬的事情,以确保他们在适当的时候与父母分离。 更重要的是,我觉得这与垃圾收集环境格格不入

我要找的是一个策略。如何检测控件或对象不可访问并将其返回到缓存,而不是让使用者对此负责

我曾研究过使用Finilizer将对象从死状态带回缓存,但这种做法通常被认为是不好的,原因有几个。此外,它也不能完全满足我的要求——它告诉我对象将要被收集的时间,而不是无法访问的时间


什么是好方法?

如果您想知道对象是否已完成/垃圾收集,可以存储对它的弱引用,并检查IsAlive属性以确定引用是否已垃圾收集。瞧,罗恩,在我写问题之前,我确实研究过weakreference。我没有提到它们,因为它们没有为我提出的问题提供解决方案。它们会告诉您对象是否已被垃圾收集。还有一种方法可以在即将收集时得到通知:对象上的终结器也会这样做。缺少的是一种安全地把它带回来的方法,以及一种能够立即发现它不可访问的方法,而不是在GC清理它的时候。我很确定,一旦对一个对象的所有引用都被释放,并且该对象已经准备好被GC处理,您就无法控制拦截和回收该对象了。一旦运行对象终结器或Dispose方法,就必须认为该对象不可用。因为你不能控制当你的缓存用户调用终结器或处理时,你必须考虑一旦你发送对象,它就消失了。是的,这就是为什么在我的帖子中,我说这个实践通常被认为是坏的好几个原因……