我知道内联代码更可取,但需要一堆代码来表明问题确实发生了(例如泄漏检测)。该项目可在此处下载:http://www.filefactory.com/file/c40b856/n/TestPopupLeak.zip
发生了什么:
出于某种原因,使用TiltEffect的弹出窗口会导致其中的最后一个实例(我想是最后一个子实例)泄漏。我创建了一个小的POC应用程序来显示这一点。
在这个(我能创建的最小的repo)中,您可以执行以下操作:
- 点击屏幕上的按钮——它只是页面上的一个按钮
--->将出现另一个按钮(此按钮在弹出窗口上)
- 点击刚刚出现的第二个按钮
---->第二个按钮将消失。
-
重复步骤1和2几次。
-
点击页面标题几次(这会导致GC.Collect())。
-
查看输出窗口,您将看到一个Grid实例和一个MyUserControl实例正在泄漏。
在我看来,最后一个例子似乎被留在了记忆中。
如果你从弹出窗口中删除倾斜效果(注释掉调用TiltEffect的行),你会看到实例被释放(输出窗口会告诉你内存中没有引用)。
我不知道为什么会发生这种事。。。尝试对TiltEffect进行调试,看起来所有事件都被取消了连接。
以下是弹出并隐藏它的代码(其余代码处理内存泄漏和愚蠢的用户控制):
public partial class MainPage : PhoneApplicationPage
{
Popup popup;
Grid grid;
// Constructor
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
// This creates a Popup with a MyUserControl in it (wrapped in a grid).
// MyUserControl just contains a single button that when pressed calls the .action
// member.
popup = new Popup();
InstanceTracker.DebugAddObject(popup);
grid = new Grid() { Width = 400, Height = 400 };
// This tracks memory leaks and will output every 10 seconds what objects are
// still alive.
InstanceTracker.DebugAddObject(grid);
MyUserControl control = new MyUserControl();
control.action = () => button_Click(null, null);
InstanceTracker.DebugAddObject(control);
grid.Children.Add(control);
// Comment out this line and the one below that has a similar comment
// to make the bug go away.
Microsoft.Phone.Controls.TiltEffect.SetIsTiltEnabled(grid, true);
// That's it, show the popup.
popup.Child = grid;
popup.IsOpen = true;
}
void button_Click(object sender, RoutedEventArgs e)
{
// Disable the tilt and close the popup. Get rid of roots.
// Comment this out to make the problem go away.
Microsoft.Phone.Controls.TiltEffect.SetIsTiltEnabled(popup, false);
popup.IsOpen = false;
popup = null;
grid = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
private void PageTitle_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
// Collects all memory.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
我不知道如何修复泄漏,但我可以建议一个替代方案。我写了一个附加行为,为元素添加了倾斜,你可以在我的博客上读到它。我认为使用工具包倾斜要容易得多,只需将属性附加到一个元素:
<Button local:MetroInMotion.Tilt="6"/>
您还可以通过希望元素倾斜的程度进行配置。
好的,问题是倾斜效果中的情节提要引用了最后一个动画对象