2012-12-11 53 views
5

我在OnNavigatedTo訂閱各種事件像我是否需要取消訂閱c#metro應用程序中的事件?

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

我沒有退訂此事件。當這個頁面不需要時它會導致任何內存問題?

+0

最好的做法是在完成時取消訂閱事件處理程序 –

+0

@MitchWheat我應該在哪裏取消訂閱?從'OnNavigatedFrom' ?? –

+0

@LewisBenge何時會被析構者稱爲?如果我將它的方法訂閱到某個其他對象的事件/代理。在這種情況下,它會被垃圾收集? –

回答

2

。在這種情況下,您不需要退訂以避免內存泄漏。原因是您訂閱了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(); 
    } 
} 
+0

+1感謝您的觀點 –

1

記住:

  1. 你可能會不小心訂閱事件幾次(使用 - =避免這種情況)。
  2. 如果事件處理程序是來自某個其他對象的方法,那麼該方法不會被垃圾收集,直到方法訂閱了一個事件。
+0

+1 @Anton你有任何鏈接或引用你的第二個b'cause我正在尋找相同的:) –

2

是的,你確實有一些事件,這可能會在Metro應用

例如可以自動發射退訂:

活動如

Window.Current.SizeChanged += Current_SizeChanged; 

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

這些事件都沒有由你控制,因爲它們在後臺着火。這可能不是涉及到一個特定頁面的任何事件(假設上述事件中的OnNavigatedTo事件initilized),那麼你必須從中可以退訂的事件,如OnNavigatedFrom

爲了進一步澄清初始化此事件

Window.Current.SizeChanged += Current_SizeChanged; 

只需保留一個斷點並將窗口大小從橫向更改爲快照模式,並且除非您未退訂該事件,否則此事件將觸發。

+0

我會檢查... –

相關問題