C# 如果要调用的方法被垃圾回收,Dispatcher.Invoke会发生什么情况?

C# 如果要调用的方法被垃圾回收,Dispatcher.Invoke会发生什么情况?,c#,garbage-collection,dispatcher,C#,Garbage Collection,Dispatcher,我有这样的代码: var myTimer = new Timer(500); myTimer.Elapsed += (o, a) => { Application.Current.Dispatcher.Invoke(() => { // Handle elapsed }, DispatcherPriority.Render); }; 如果计时器超时并将匿名方法添加到Dispatcher,然后在Dispatcher调用匿名方法之前立即超出范围并

我有这样的代码:

var myTimer = new Timer(500);
myTimer.Elapsed += (o, a) =>
{
    Application.Current.Dispatcher.Invoke(() =>
    {
        // Handle elapsed
    }, DispatcherPriority.Render);
};

如果计时器超时并将匿名方法添加到Dispatcher,然后在Dispatcher调用匿名方法之前立即超出范围并收集垃圾,会发生什么?

它的生存期不会特别结束,因为消息循环正在引用它

即使对象不再在代码中的作用域中,也可以通过根对象访问该对象,因此GC无法收集它


使用托管内存的全部意义在于,当不可能从可执行代码访问托管资源时,您可以依靠GC来回收任何托管资源。如果可执行代码可以访问对象,则不会收集该对象。

由于消息循环正在引用该对象,因此该对象的生存期不会特别结束

即使对象不再在代码中的作用域中,也可以通过根对象访问该对象,因此GC无法收集它


使用托管内存的全部意义在于,当不可能从可执行代码访问托管资源时,您可以依靠GC来回收任何托管资源。如果可执行代码可以访问某个对象,则不会收集该对象。

但问题表示在事件期间收集。那可能是可能的,但是(因为)它仍然没有任何后果。因此,在经过范围内创建的匿名方法被视为计时器的引用?@HenkHolterman他特别说,他想知道在调度器添加该方法后是否可以收集该匿名方法。@ConditionRacer您调用的匿名方法是的局部变量您将匿名方法指定为计时器的处理程序,它是一个局部变量,无论整个事件属于哪个范围。当您将外部lambda添加为事件的处理程序,或将内部lambda添加到消息队列时,您正在将对这些已创建对象的引用复制到其他位置;其生存期可能不同于对象实例最初分配给的局部变量的生存期的位置。@Servy这很有意义。谢谢,但问题是指活动期间的收集。那可能是可能的,但是(因为)它仍然没有任何后果。因此,在经过范围内创建的匿名方法被视为计时器的引用?@HenkHolterman他特别说,他想知道在调度器添加该方法后是否可以收集该匿名方法。@ConditionRacer您调用的匿名方法是的局部变量您将匿名方法指定为计时器的处理程序,它是一个局部变量,无论整个事件属于哪个范围。当您将外部lambda添加为事件的处理程序,或将内部lambda添加到消息队列时,您正在将对这些已创建对象的引用复制到其他位置;其生存期可能不同于对象实例最初分配给的局部变量的生存期的位置。@Servy这很有意义。ThanksCode不会被垃圾收集,它只会在AppDomain卸载后消失。如果捕获了任何变量(不在代码中),则下面可能有一个隐藏类的对象。存储在调用队列中的委托保留对它的引用。代码不会被垃圾收集,它只会在AppDomain卸载后消失。如果捕获了任何变量(不在代码中),下面可能有一个隐藏类的对象,则存储在调用队列中的委托将保留对该对象的引用。