gpt4 book ai didi

silverlight - 是否应该将 Silverlight 控件重新加载到页面上?

转载 作者:行者123 更新时间:2023-12-02 04:11:07 24 4
gpt4 key购买 nike

几个月前,我开始自己开发 Silverlight 应用程序。我很快发现我无法为我的大多数控件获得预期的垃圾收集。我用 WinDBG 和 ANTS 内存分析器苦苦挣扎了大约一周,然后在 Silverlight 论坛 (http://forums.silverlight.net/forums/t/171739.aspx) 上发现了“DataTemplate 内存泄漏”链。

鉴于这么多人似乎对各种内存问题感到沮丧,我决定推迟对内存情况的进一步调查,直到最明显的问题得到解决。

无论如何,现在我再次研究这个问题,我意识到我遇到的问题比我最初想象的要根本得多。在以下情况下,我根本没有编写可收集垃圾的 Silverlight 控件的范例:a) 控件具有可以绑定(bind)到的依赖属性,b) 控件可以从一个控件中卸载,然后再次加载。

我开始认为第二个要求太高了。谁能证实这一点?

为了提供更多细节,我能想到的用于编写好的、可垃圾收集的 Silverlight 控件的最强大的模式如下:

1)当应用控件的模板时(在 OnApplyTemplate 覆盖中),我设置了本地属性和 TemplateParts 之间的任何内部绑定(bind)。例如,我可能会在名为 CanSearch 的本地属性和按钮之间设置一个绑定(bind)。

if (x_Button_Search != null)
{
Binding b = new Binding("CanSearch");
b.Source = this;
this.x_Button_Search.SetBinding(Button.IsEnabledProperty, b);
}

2) 当控件引发 Unloaded 事件时,我清除内部绑定(bind)并取消连接任何事件处理程序。
if (x_Button_Search != null)
{
this.x_Button_Search.ClearValue(Button.IsEnabledProperty);
}

这似乎是确保 x_Button_Search 元素和控件之间不存在尾随引用的最简洁方法。我不知道这是否是绝对必要的。

3) 同样,当 Control 引发 Unloaded 事件时,我清除与现有依赖项属性的绑定(bind)。
 this.ClearValue(SearchParametersProperty);

如果我不这样做,我可能会导致泄漏。例如,如果 SearchParameters 属性绑定(bind)到某个 INotifyPropertyChanged 对象,那么即使在卸载控件后,对控件的引用仍保留在绑定(bind)到的 INotifyPropertyChanged 对象上的 PropertyChanged 事件中,即 View 将一直存在,只要模型,这可能不是我们想要的。

4) 我“闪烁”模板值,以便下次加载控件时,重新应用模板并再次触发 OnApplyTemplate 方法。
var oldTemplate = this.Template;
this.Template = null;
this.Template = oldTemplate;

做 4 的原因是当控件重新加载到页面上时我需要恢复绑定(bind)。在 Silverlight 中,有两个入口点可以执行此操作:在 OnApplyTemplate 覆盖中或在控件触发 Loaded 事件之后。由于我想在加载控件之前强制绑定(bind)值(以避免闪烁),因此只有一个可用的入口点 OnApplyTemplate。我必须闪烁模板才能在重新加载控件时强制模板重新应用。

直到第 3 点为止,这种模式似乎是提供垃圾收集控件的最低要求。

当您想卸载控件(例如从面板中删除它)并随后重新加载它时,我的问题就出现了。在第 3 点中,控件上的任何依赖属性都已设置为 null。例如,假设控件的声明中有一个绑定(bind),例如.据我所知,一旦 SearchParameters 的值设置为 null,就无法恢复此绑定(bind),毕竟它不是模板的一部分。结果是,当重新加载控件时,就好像 SearchParameters 的值为 null。所以我要么跳过模式中的第 3 步,得到一个不被垃圾回收的可重载控件,要么我保留第 3 步,得到一个不可重载的控件。

最佳答案

你在 1) 中所做的事情看起来真的很奇怪。为什么在代码中而不是在 xaml 中启动与模板的绑定(bind)?
我们已经使用这个软件解决了 silverlight 中的许多内存泄漏问题

http://memprofiler.com/

编辑

为了更好地控制绑定(bind),您可以使用

{Binding Property, RelativeSource={RelativeSource TemplatedParent}}

这样,隐式转换器可以按预期使用,您也可以指定自己的。而且我相信 BindingMode TwoWay 也可以。
祝你好运!

关于silverlight - 是否应该将 Silverlight 控件重新加载到页面上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5127917/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com