2011-02-24 41 views
3

我正在開發一個GUI應用程序,它非常依賴Action<>委託來定製我們的UI工具的行爲。我想知道我們這樣做的方式是否有任何潛在的問題,例如實現是否保持對捕獲變量的引用,聲明委託等的類實例?如何在C#中正確釋放匿名代理/關閉?

假設我們有這個類MapControl,它包裝了一個有狀態的GUI控件。該地圖具有不同種類的工具(繪圖,選擇等),由ITool界面表示。您可以使用StartTool()設置該工具,但一次只能有一個工具處於活動狀態,因此當設置了另一個工具時,前一個工具將使用StopTool()停止。當工具停止時,執行調用者指定的回調委託。

public class MapControl 
{ 
    ITool _currentTool; 
    Action<IResult> _onComplete; 

    public void StartTool(ToolEnum tool, Action<IResult> onComplete) { 

     //If tool is active, stop it first 
     if (_currentTool != null) StopTool(); 

     _onComplete = onComplete; 

     //Creates a tool class, etc. 
     _currentTool = CreateTool(tool) as ITool; 
    } 

    public void StopTool() { 

     //Execute callback delegate 
     IResult result = _currentTool.GetResult(); 
     if (_onComplete != null) 
      _onComplete(result); 

     //Nix the references to callback and tool 
     _onComplete = null; 
     _currentTool = null; 
    } 
} 

在應用程序的ViewModel類我們設置這樣一些工具:

class ViewModel 
{ 
    private MapControl _mapControl = new MapControl(); 
    public void SetSomeTool() 
    { 
     //These variables will be captured in the closure 
     var someClassResource = this.SomeClassResource; 
     var someLocalResource = new object(); 

     //Start tool, specify callback delegate as lambda 
     _mapControl.StartTool(ToolEnum.SelectTool, (IResult result) => { 

      //Do something with result and the captured variables 
      someClassResource.DoSomething(result, someLocalResource); 
     }); 
    } 
} 

在我們的例子中ViewModel類連接到一個WPF應用程序的主窗口,並且只能有一個實例ViewModel在應用程序生命週期內。如果情況不是這樣,它會改變什麼嗎?宣佈代表的類會更短暫嗎?

我的問題是,我是否正確處置了回調委託?是否有任何情況下,這可能導致內存膨脹通過堅持引用它不應該?

更一般地說,處置匿名代表的安全和正確的方式是什麼?

回答

2

恕我直言,這是好的,你沒有堅持任何引用你不需要。清除StopTool中的引用後,您不再持有它們。

+0

我同意,我沒有看到有理由這樣做。我想將所有本地參考變量設置爲空:P – vtortola 2011-02-24 10:13:13

+0

不完全正確。如果在StartTool的上下文中沒有調用StopTool,則將這些引用設置爲null是正確的。 – 2011-02-24 10:14:23

+0

@fencliff:如果我的回答對你有幫助,請好好接受它。 – 2011-02-24 15:38:45

0

我覺得更恰當的方法是:

_onComplete = (Action<IResult>)Delegate.Remove(null, _onComplete); 
+3

是否有任何理由這樣做?根據MSDN,Delegate.Remove返回null,如果第一個參數爲null,那麼它應該等同於OP所做的。 – 2011-02-24 10:17:57

2

你正在做的罰款取出參考方法的方式。


還有一件事你問:

我的問題是,我在配置回調代表的正確?

您不需要配置方法(或指向方法的指針),只有類。

0

如果您想確保正確處理所有未使用的對象,我建議您使用像CLR Profiler這樣的工具,以便您可以全面瞭解應用程序如何分配/釋放內存。