且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

BUG:WP8命令绑定内存泄漏

更新时间:2023-01-12 18:08:10

Mutari,

非常感谢您举报此事.这似乎是一个已知问题,已记录到我们的问题数据库中.这是Silverlight特有的问题,我希望在将来的操作系统更新中可以修复此问题.

将命令对象绑定到命令"时, ButtonBase的属性,将ButtonBase注册到命令对象的CanExecuteChanged事件.这将创建对对象实例的强引用.

然后,如果可视树发生变化(例如,通过在ContentControl中加载新的DataTemplate),则该按钮当然不会被垃圾收集,甚至会阻止所有父控件也被垃圾收集. /p>

正确的行为应该是使用"WeakEventListener"就像一个ItemsControl一样,它监听一个集合的更改事件.

您可以通过遵循以下Silverlight线程中描述的模式(在WeakEventSource中搜索线程)来实现变通方法:

命令绑定内存泄漏

希望这会有所帮助,
标记


Command binding prevents a control from being GCed.

I tried SL4, WPF, WP8 and it seems this is only WP8 bug\behavior.

Example app is uploaded to my skydrive folder: https://skydrive.live.com/?cid=c6bca5f19c01f4f7&id=C6BCA5F19C01F4F7%214744

In short: you need 3 things to repro it:
1) VirtualizingStackPanel.VirtualizationMode="Standard" on a list, so it recreates containers instead of reusing them.
2) Command="{Binding TestCommand}" inside any button in DataTemplate
3) A UserControl in the same data template next to the button, with some private byte array to emulate heavy memory usage like images do. Also put a finalizer there with output logging to see it never actually be called until OOM.

Hi Mutari,

Thank you very much for reporting this. This appears to be a known issue that has been logged into our issues database. It is a Silverlight specific issue and I would anticipate that a fix will be rolled into a future OS update.

When a command object is bound to the "Command" property of a ButtonBase, the ButtonBase registers to the CanExecuteChanged event of the command object. This creates a strong reference to the object instance.

Then, if the visual tree changes (for example, by loading a new DataTemplate in a ContentControl), the button is, of course, not garbage collected, and will even prevent all the parent controls from being garbage collected also.

The correct behavior should be to use a "WeakEventListener" like an ItemsControl listening to the change events of a collection.

You can implement the workaround by following the pattern described in the following Silverlight thread (search the thread for WeakEventSource):

Command Binding Memory Leak

Hope this helps,
Mark