是否需要取消订阅 c# metro 应用程序中的事件



我已经订阅了各种OnNavigatedTo事件,例如

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Loaded += Screen_Loaded;
}

我尚未取消订阅此活动。不需要此页面时是否会导致任何内存问题?

No.在这种情况下,您无需取消订阅以避免内存泄漏。原因是您在 this 上订阅了一个事件。垃圾回收器必须标识这一点并释放对象。

但是,由于其他原因,我仍然会退订。例如,拥有平衡的资源使代码更易于阅读。另外,如果OnNavigatedTo被调用两次怎么办?(实际上不知道这是否会发生)然后,你将有两个对同一方法的订阅。有些人会争辩说,在这种情况下取消订阅是多余的代码并删除它。虽然这样是正确的,但我反对这样的论点。

您可以尝试此简短片段自己尝试一下。注意:除了了解本例中的 GC 外,切勿使用用户终结器或GC.Collect()

public class Program
{
    private class Foo
    {
        public event EventHandler FooChanged;
        ~Foo()
        {
            Console.WriteLine("Foo was collected");
        }
        public void Bar()
        {
            FooChanged += UpdateUI;
        }
        private void UpdateUI(object sender, EventArgs e)
        {
        }
    }
    public static void Main(string[] args)
    {
        var foo = new Foo();
        foo.Bar();
        foo = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine("End of program");
        Console.ReadKey();
    }
}

是的,您必须取消订阅某些可能在地铁应用程序中自动触发的事件

例如:

诸如此类的事件

Window.Current.SizeChanged += Current_SizeChanged;
void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
    //your code block contining various objects and logic
}

这些事件不受您的控制,因为它们在后台触发。任何可能与特定页面无关的事件(假设上述事件是在OnNavigatedTo事件中启动的),那么您必须在OnNavigatedFrom 等事件中取消订阅它

如需进一步说明,请初始化此事件

Window.Current.SizeChanged += Current_SizeChanged;

只需保留一个断点并将窗口大小从横向更改为贴靠模式,除非您尚未取消订阅该事件,否则此事件将触发。

请记住:

  1. 您可能会意外地多次订阅事件(使用 -= 来避免这种情况)。
  2. 如果事件处理程序是来自其他某个对象的方法,则在订阅事件的方法之前,不会对该对象进行垃圾回收。

相关内容

最新更新