使用匿名委托进行事件处理 [英] Event handling with an anonymous delegate

查看:170
本文介绍了使用匿名委托进行事件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

记录:我发现一个类似的问题这里,但是我必须详细说明一下这个问题。

For the record: I found a similar question here but I have to elaborate a bit more on on the subject.

我的具体情况是这样的:

My concrete scenario is this:

在Silverlight 4中, myFrameworkElement.FindName(otherElementName)方法似乎工作正常,但我遇到了一个问题。当元素尚未添加到视觉树中时,它仍然返回 null

In Silverlight 4, The myFrameworkElement.FindName("otherElementName") method seems to work fine now, but I encountered a problem. It still returns null when the element is not yet added to the visual tree obviously.

但现在我需要这个自定义 UserControl DependencyProperty PropertyChangedCallback 处理程序。在这个范围内,还不确定UserControl是否被添加到视觉树。但是我必须对树中的另一个元素执行某个动作。当元素已经可用时,它可以并且应该在现在完成。如果没有,它必须在可用时立即完成。所以我想出了这种扩展方法,我可以这样调用:

But now I need this functionality in a DependencyProperty's PropertyChangedCallback of a custom UserControl handler. In this scope, it is uncertain if the UserControl is added to the visual tree yet. But I must execute a certain action on another element in the tree. When the element is already available, it can and should be done right now. If not, it must be done immediately when it is available. So I came up with this extension method that I can call like this:

myFrameworkElement.FindNameEnsured("otherElementName",
    result => this.DoSomethingWith(result));

扩展方法的代码如下所示:

The code for the extension method goes like this:

    static public void FindNameEnsured(this FrameworkElement self,
            string name, Action<object> resultAction)
    {
        if (self != null && resultAction != null)
        {
            object result = self.FindName(name);

            if (result != null)
            {
                resultAction(result);
            }
            else
            {
                RoutedEventHandler handler = null;
                handler = (sender, e) =>
                     {
                         result = self.FindName(name);
                         resultAction(result);

                         self.Loaded -= handler;
                     };

                self.Loaded += handler;
            }
        }

正如你所看到的,我必须使用匿名委托因为我需要处理程序内的名称 resultAction 的值。然后我取消订阅处理程序内的事件,因为我是一个聪明干净的家伙,不想泄漏。我也不想在这里用任何幻想的WeakEventFactories或类似的东西打破轮子上的苍蝇。

As you can see, I must use an anonymous delegate because I need the values for name and resultAction inside of the handler. I then go unsubscribe the event inside of the handler because I'm a smart and clean guy and want no leakage. I also don't want to break any flies on wheels here with some fancy WeakEventFactories or similar stuff.

现在这个工作很顺利。但是我有一些问题。

Now this works smoothly so far. But I have some questions.


  1. 这通常是一个干净的方法来取消订阅处理程序内的事件处理程序?或者是要最终杀死一只无辜的小狗?

  2. 由于在匿名委托中使用外部范围变量,是否会有一些漏洞?

  3. <有可能会出现线程同步问题,这会导致我错过加载的事件?在这种特殊情况下,只应该参与Silverlight的UI调度程序线程。但是,如果这是一个问题,和/或如果我在非UI相关的场景中需要类似的功能,那么f1x0r的最佳方法是什么?
  1. Is this generally a clean enough approach to unsubscribe the event handler inside of the handler? Or is that going to kill an innocent puppy eventually?
  2. Could there be some issues like some leakage because of using outer scope variables inside the anonymous delegate?
  3. Can there be thread synchronization issues which would cause me to "miss" the Loaded event? In this special scenario, only the Silverlight's UI dispatcher thread should be involved. But if it's a problem anyway, and/or if I need a similar functionality in a non-UI related scenario, what's the best approach to f1x0r it?

感谢您的耐心和时间阅读我的漫长的阐述。 ; - )

Thanks already for your patience and time reading my lengthy elaborations. ;-)

推荐答案


  1. 这应该是罚款,虽然有点痛苦。 LINQ to Rx有一个更好的取消订阅的想法 - 当您订阅时,您将得到一个 IDisposable ,在处理该文件时取消订阅。这不符合现有的事件模型。

  2. 在这种情况下,我不认为你会有任何泄漏 - 有两个不同的匿名函数使用变量的边缘条件在相同的范围内,每个人都可以最终获取不需要的变量,但它确实是一个边缘案例。

  3. 你必须给出更多关于假设情况的确切细节 - 什么你真的很担心事件的实现等等。

  1. That should be fine, although it's a bit painful. LINQ to Rx has a nicer idea of unsubscription - when you subscribe, you're given an IDisposable which unsubscribes when you dispose it. That doesn't fit the existing event model though.
  2. I don't think you'll have any leakage in this particular case - there are some edge conditions where two different anonymous functions using variables in the same scope can each end up capturing variables they don't require, but it really is an edge case.
  3. You'd have to give more exact details about the hypothetical situation - what you were worried about exactly, how the event is implemented etc.

这篇关于使用匿名委托进行事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆