匿名代表何时从活动中删除?

发布于 2024-10-19 06:51:09 字数 1180 浏览 7 评论 0原文

如果我写类似

myDataModel.ContentLoaded += (o,e) => { DoSomething(); }

什么时候(如果有的话)匿名委托会从事件中删除吗?

作为一个简单的例子,我可以编写这个程序

class Program
{
    public event EventHandler<EventArgs> MyEvent = delegate { };

    static void Main(string[] args)
    {
        Program p = new Program();
        while(true)
        {
            p.MyEvent += (o, e) => Console.WriteLine("Hello!");

            Console.ReadLine();
            p.Foo();
        }
    }

    void Foo()
    {
        MyEvent(this, EventArgs.Empty);
    }
}

,当我重复按“Enter”键时,输出是

Hello!

Hello!
Hello!

Hello!
Hello!
Hello!

Hello!
Hello!
Hello!
Hello!

......等等。我可以在 p.Foo() 之后添加该行,

p.MyEvent -= (o, e) => Console.WriteLine("Hello!");

但当然它没有任何效果,因为我正在删除一个完全不同的匿名委托。

那么这到底是怎么回事呢?有什么办法可以完全删除这些匿名代表吗?例如,对于使用诸如 之类的表达式提取数据的异步 Silverlight 应用程序,这意味着什么

_myDataContext.Load(myQuery, loadOperation =>
    {
        // do stuff with the data here
    }, null);

?我假设这些类型的回调不是使用事件实现的,但当然这是不可能(?)告诉的。

如果不仔细考虑的话,匿名代表会危险吗?

If I write something like

myDataModel.ContentLoaded += (o,e) => { DoSomething(); }

When (if ever) is that anonymous delegate removed from the event?

As a quick example, I could write this program

class Program
{
    public event EventHandler<EventArgs> MyEvent = delegate { };

    static void Main(string[] args)
    {
        Program p = new Program();
        while(true)
        {
            p.MyEvent += (o, e) => Console.WriteLine("Hello!");

            Console.ReadLine();
            p.Foo();
        }
    }

    void Foo()
    {
        MyEvent(this, EventArgs.Empty);
    }
}

And the output as I press 'Enter' repeatedly is

Hello!

Hello!
Hello!

Hello!
Hello!
Hello!

Hello!
Hello!
Hello!
Hello!

...and so forth. I could add the line

p.MyEvent -= (o, e) => Console.WriteLine("Hello!");

after p.Foo() but of course it has no effect because I'm removing an entirely different anonymous delegate.

So what's the deal with this? Is there any way of removing these anonymous delegates at all? What are the implications for, say, an asynchronous Silverlight application where I'm pulling data using expressions like

_myDataContext.Load(myQuery, loadOperation =>
    {
        // do stuff with the data here
    }, null);

? I assume that these kinds of callbacks aren't implemented using events, but of course it's impossible(?) to tell.

Are anonymous delegates dangerous if not carefully accounted for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘴硬脾气大 2024-10-26 06:51:09

没有(简单)方法可以删除您未首先分配给任何变量的委托。他们是否匿名并不重要。您可以将匿名委托分配给变量并稍后将其删除:

EventHandler eh = (src, e) => Console.WriteLine("Hello");
form.Click += eh; 
// At some later point
form.Click -= eh;

同样,如果您使用以下方法注册委托,则没有(简单)方法可以删除委托:

form.Click += new EventHandler(foo);

事件的问题在于,它们仅在附加对象时才被垃圾收集to 被垃圾收集(即使它们使用的目标对象没有从程序的任何其他部分引用,因此它们无法执行任何有用的工作)。

这可以使用弱事件来解决。您无需显式删除它们,而是使用一些允许 GC 自动处理它们的机制。

There is no (easy) way to remove delegates that you didn't first assing to any variable. It doesn't really matter whether they're anonymous or not. You can assign anonymous delegate to a variable and remove it later:

EventHandler eh = (src, e) => Console.WriteLine("Hello");
form.Click += eh; 
// At some later point
form.Click -= eh;

Similarly, there is no (easy) way to remove delegate if you register it using:

form.Click += new EventHandler(foo);

The problem with events is that they are only garbage collected when the object that they're attached to is garbage collected (even if the target object that they work with is not referenced from any other part of program and so they cannot do any useful work).

This can be solved using weak events. Instead of removing them explicitly, you use some mechanims that allows GC to deal with them automatically.

层林尽染 2024-10-26 06:51:09

它永远不会自动从活动中删除。

如果您想取消订阅匿名委托,请查看以下问题:

取消订阅 C# 中的匿名方法

It will never be automatically removed from the event.

If you want to unsubscribe an anonymous delegate, check out this question:

Unsubscribe anonymous method in C#

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文