Windows phone 7 Windows Phone 7(Mango)内存泄漏与ControlTemplate

Windows phone 7 Windows Phone 7(Mango)内存泄漏与ControlTemplate,windows-phone-7,memory,memory-leaks,controltemplate,Windows Phone 7,Memory,Memory Leaks,Controltemplate,使用ControlTemplate时,我的WP7应用程序中存在托管内存泄漏 这可以在一个香草WP7.1项目中使用所附的代码进行复制 请参阅下面的“取消注释以查看问题” 只需在测试应用程序中向前和向后导航即可。我希望Page1.xaml是垃圾收集的,但在定义ControlTemplate时不是这样的 不带ControlTemplate的输出: 在 在里面 在里面 出来 在里面 出来 在里面 出来 在里面 出去 使用ControlTemplate进行输出: 在 在里面 在里面 在里面 在里面 在里面

使用ControlTemplate时,我的WP7应用程序中存在托管内存泄漏

这可以在一个香草WP7.1项目中使用所附的代码进行复制

请参阅下面的“取消注释以查看问题”

只需在测试应用程序中向前和向后导航即可。我希望Page1.xaml是垃圾收集的,但在定义ControlTemplate时不是这样的

不带ControlTemplate的输出:

在 在里面 在里面 出来 在里面 出来 在里面 出来 在里面 出去

使用ControlTemplate进行输出:

在 在里面 在里面 在里面 在里面 在里面 在

在任何一种情况下,当应用程序退出时,您都会看到剩余的调试“Out”语句正在打印

有人知道为什么“ControlTemplate”的定义会导致页面保留在内存中吗

非常感谢您的帮助

乔恩

MainPage.xaml 第1.xaml页
这似乎是一个非常常见的内存泄漏,特别是因为标准WP7应用程序(非XNA应用程序)使用相同的基本Silverlight类。对于这个问题,有一个完整的解决方案

最初,解决方案是使用内联模板,但泄漏仍然存在于我的测试用例中。如果将模板移动到
App.xaml
,则泄漏不再存在

<phone:PhoneApplicationPage 
    x:Class="PhoneApp1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">            
        <Button Click="Button_Click">
        <TextBlock Text="Click me..." />
        </Button>          
    </Grid>
    </Grid>

</phone:PhoneApplicationPage>
using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
namespace PhoneApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        GC.Collect();
    }
    }
}
<phone:PhoneApplicationPage 
    x:Class="PhoneApp1.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    shell:SystemTray.IsVisible="True" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480">

    <phone:PhoneApplicationPage.Resources>
    <Style x:Key="CheckBoxButtonStyle" TargetType="CheckBox">
        <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="CheckBox">
            <!-- Uncomment the following to see the problem -->
            <!--<Grid Background="Transparent"></Grid>-->
            </ControlTemplate>
        </Setter.Value>
        </Setter>
    </Style>
    </phone:PhoneApplicationPage.Resources>

    <Grid x:Name="LayoutRoot" Background="Transparent"></Grid>
</phone:PhoneApplicationPage>
using System.Diagnostics;
using Microsoft.Phone.Controls;

namespace PhoneApp1
{
    public partial class Page1 : PhoneApplicationPage
    {
    public Page1()
    {
        InitializeComponent();
        Debug.WriteLine("In");
    }

    ~Page1()
    {
        Debug.WriteLine("Out");
    }
    }
}