您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用匿名委托进行事件处理时的垃圾回收

使用匿名委托进行事件处理时的垃圾回收

我知道这个问题是古老的,但是地狱-我找到了,我认为其他人也可能如此。我正在尝试解决一个相关问题,可能会有一些见识。

您提到了达斯汀·坎贝尔(Dustin Campbell)的WeakEventHandler- 实际上,它确实无法与匿名方法一起使用。当我意识到a)在99%的情况下我需要这样的东西时,我正在尝试摆弄一些东西,他最初的@R_419_2422@案会更安全,并且b)在少数情况下我必须(注意:拥有)而不是“因为lambda太漂亮和简洁了”),如果您有点聪明,就有可能使它起作用。

您的示例似乎完全是一次性的情况,其中有些棘手的问题可能会导致一个相当简洁的@R_419_2422@案。

public static class Linker {
    public static void Link(Publisher publisher, Control subscriber) {
        // anonymous method references the subscriber only through weak 
        // references,so its existance doesn't interfere with garbage collection
        var subscriber_weak_ref = new WeakReference(subscriber);

        // this instance variable will stay in memory as long as the  anonymous
        // method holds a reference to it we declare and initialize  it to 
        // reserve the memory (also,  compiler complains about uninitialized
        // variable otherwise)
        EventHandler<ValueEventArgs<bool>> handler = null;

        // when the handler is created it will grab references to the  local 
        // variables used within, keeping them in memory after the function 
        // scope ends
        handler = delegate(object sender, ValueEventArgs<bool> e) {
            var subscriber_strong_ref = subscriber_weak_ref.Target as Control;

            if (subscriber_strong_ref != null) 
                subscriber_strong_ref.Enabled = e.Value;
            else {
                // unsubscribing the delegate from within itself is risky, but
                // because only one instance exists and nobody else has a
                // reference to it we can do this
                ((Publisher)sender).EnabledChanged -= handler;

                // by assigning the original instance variable pointer to null
                // we make sure that nothing else references the anonymous
                // method and it can be collected. After this, the weak
                //  reference and the handler pointer itselfwill be eligible for
                // collection as well.
                handler = null; 
            }
        };

        publisher.EnabledChanged += handler;
    }
}

据传WPF弱事件模式会带来很多开销,因此在这种特殊情况下,我将不使用它。此外,在WinForm应用程序中引用核心WPF库似乎也很繁重。

其他 2022/1/1 18:16:47 有562人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶