我正在开发一个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
在应用程序生命周期内。如果情况不是这样,它会改变什么吗?宣布代表的类会更短暂吗?
我的问题是,我是否正确处置了回调委托?是否有任何情况下,这可能导致内存膨胀通过坚持引用它不应该?
更一般地说,处置匿名代表的安全和正确的方式是什么?
我同意,我没有看到有理由这样做。我想将所有本地参考变量设置为空:P – vtortola 2011-02-24 10:13:13
不完全正确。如果在StartTool的上下文中没有调用StopTool,则将这些引用设置为null是正确的。 – 2011-02-24 10:14:23
@fencliff:如果我的回答对你有帮助,请好好接受它。 – 2011-02-24 15:38:45