【问题标题】:Using WeakEventManager in Windows.Forms application在 Windows.Forms 应用程序中使用 Wea​​kEventManager
【发布时间】:2009-08-19 13:15:25
【问题描述】:

在 Windows.Forms 应用程序中使用 http://wekempf.spaces.live.com/blog/cns!D18C3EC06EA971CF!373.entry 中所述的弱事件时,WeakEventManager 会泄漏 WeakReference 对象。 我认为这是因为没有 WPF 消息循环,CleanupOperation 永远不会执行,尽管在 WeakEventManager.ProtectedAddListener 中调用了 ScheduleCleanup。

作为一种解决方法,我实现了一个清理功能,如下所示:

internal bool Cleanup()
{
    // The following is equivalent to 
    //    return this.Table.Purge(false);
    // but we need to use reflection to access the private members.

    PropertyInfo pi = typeof(WeakEventManager).GetProperty("Table", BindingFlags.Instance | BindingFlags.NonPublic);
    if (pi == null)
        return false;
    object table = pi.GetValue(this, null);
    MethodInfo mi = table.GetType().GetMethod("Purge", BindingFlags.Instance | BindingFlags.NonPublic);
    if (mi == null)
        return false;
    return (bool)mi.Invoke(table, new object[] { false });
}

并在每个例如之后调用它第 16 次致电ProtectedAddListener

这行得通,但显然我喜欢避免这种(ab)使用反射。

所以我的问题是:

  1. 有没有办法使用公共/受保护的成员来实现清理功能? WeakEventManager.Purge 可能有用,但我不知道如何使用它。
  2. 是否有一种简单的方法可以在基于 Windows.Forms 的应用程序中运行 WPF 消息循环?

【问题讨论】:

    标签: c# .net events weak-events weakeventmanager


    【解决方案1】:

    此代码构建了一个静态函数,您可以保持缓存。它将消除每次运行时反射的痛苦,并且基本上做你所拥有的。将其缓存在某处并通过每次传入您的弱事件管理器来调用它。除了一次性命中(在构建/编译期间),没有进一步的反射。

        using System.Windows;
        using System.Linq.Expressions;
        using Expression = System.Linq.Expressions.Expression;
    
        static void Main(string[] args)
        {
            Func<WeakEventManager, bool> cleanUpFunction = BuildCleanUpFunction();
        }
    
        private static Func<WeakEventManager, bool> BuildCleanUpFunction()
        {
            ParameterExpression managerParameter = Expression.Parameter(
                typeof(WeakEventManager),
                "manager"
            );
            return Expression.Lambda<Func<WeakEventManager, bool>>(
                Expression.Call(
                    Expression.Property(
                        managerParameter,
                        "Table"
                    ),
                    "Purge",
                    Type.EmptyTypes,
                    Expression.Default(
                        typeof(bool)
                    )
                ),
                managerParameter
            ).Compile();
        }
    

    【讨论】:

    • +1 以获得有趣的答案,尽管性能不是我主要关心的问题。我非常感谢一个不依赖于未记录的私有函数的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    相关资源
    最近更新 更多