Утечка памяти в Windows Phone 7 (Mango) с помощью шаблона управления - PullRequest
2 голосов
/ 03 августа 2011

В приложении WP7 при использовании ControlTemplate произошла управляемая утечка памяти.

Это можно воспроизвести в ванильном проекте WP7.1 с помощью прилагаемого кода.

См. "Раскомментируйте следующее, чтобы увидеть проблему" ниже ...

Просто перемещайтесь вперед и назад в тестовом приложении. Я ожидаю, что Page1.xaml будет собирать мусор, но это не так, когда определен ControlTemplate ...

Вывод без Шаблон управления:

В В В Из В Из В Из В Из

Вывод с Шаблон управления:

В В В В В В В

В любом случае, когда приложение завершается, вы видите печать оставшихся отладочных операторов "Out".

Кто-нибудь знает, почему определение ControlTemplate может привести к тому, что страница останется в памяти?

Большое спасибо за любую помощь,

Jon

MainPage.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>

MainPage.xaml.cs

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();
    }
    }
}

Page1.xaml

<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>

Page1.xaml.cs

using System.Diagnostics;
using Microsoft.Phone.Controls;

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

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

1 Ответ

1 голос
/ 04 августа 2011

Кажется, это довольно распространенная утечка памяти, тем более что стандартные приложения WP7 (не-XNA-приложения) работают с теми же фундаментальными классами Silverlight.Существует целая тема на форумах Silverlight , посвященная этой проблеме.

Изначально решение заключалось в использовании встроенных шаблонов, но утечка все еще сохраняется в моих тестовых случаях.Если вы переместите шаблон на App.xaml, утечки больше не будет.

...