Ho incontrato una situazione in cui sto perdendo memoria non gestita quando il mouse viene spostato sulla mia app WPF. Nello specifico, quando profilo l'applicazione in perfmon
o il profilo di memoria di Red Gate, i byte privati aumentano monotonicamente, ma i byte in tutti gli heap gestiti rimangono costanti - il che, credo, significa che l'app ha una perdita non gestita.Perdita non gestita in un'applicazione WPF banale
Ho creato un'applicazione di repro banale, ma non riesco a vedere dove si trova il problema.
L'app è costituita da un controllo ListView con quattro voci. Spostare rapidamente il mouse su questi elementi causa il problema.
Ecco il codice se sei interessato a riprodurre il problema: non è bello, ma è semplice.
Grazie
Edit: Ho creato un Microsoft Connect issue per questo problema.
App.xaml
<Application x:Class="WpfLeakRepro.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace WpfLeakRepro
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<LinearGradientBrush x:Key="ListItemHover"
EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="Aqua"
Offset="0" />
<GradientStop Color="White"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ListItemSelected"
EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="Blue"
Offset="0" />
<GradientStop Color="White"
Offset="1" />
</LinearGradientBrush>
<VisualBrush x:Key="CheckeredBackground"
Viewport="20,20,20,20"
ViewportUnits="Absolute"
TileMode="Tile"
Stretch="Fill">
<VisualBrush.Visual>
<Canvas Opacity="5">
<Rectangle Fill="#FF606060"
Height="21"
Width="21"
Canvas.Top="20" />
<Rectangle Fill="#FF606060"
Width="21"
Height="21"
Canvas.Left="20" />
<Rectangle Fill="#FF646464"
Height="21"
Width="21"
Canvas.Left="20"
Canvas.Top="20" />
<Rectangle Fill="#FF646464"
Width="21"
Height="21" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border Background="{TemplateBinding Background}">
<Grid>
<GridViewRowPresenter />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="{DynamicResource ListItemHover}" />
</Trigger>
<Trigger Property="IsSelected"
Value="true">
<Setter Property="Background"
Value="{DynamicResource ListItemSelected}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Window1.xaml
<Window x:Class="WpfLeakRepro.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="449" Width="497">
<Grid>
<ListView Margin="12"
Name="listView"
ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="File Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Thumbnail">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Background="{DynamicResource CheckeredBackground}" Width="72" Height=48/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.IO;
namespace WpfLeakRepro
{
public class Picture
{
public string Name { get; set; }
}
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
List<Picture> pictures = new List<Picture>();
string[] images = new string[] {"Blue hills.jpg", "Sunset.jpg", "Water lilies.jpg", "Winter.jpg" };
foreach (string imagePath in images)
{
pictures.Add(new Picture() { Name = imagePath });
}
DataContext = pictures;
}
}
}
Non penso che questo sia il problema. 'Picture' utilizzato per implementare' INotifyPropertyChanged', ma l'ho rimosso per abbreviare la mia app di repro.Inoltre, se questo fosse il problema, credo che la perdita sarebbe gestita - il sistema di associazione dei dati manterrebbe riferimenti agli oggetti gestiti che non dovrebbe. L'elenco delle perdite di WPF è buono (e consiglio a tutti di verificarlo), ma ho esaminato tale elenco, e penso che sia valido solo il n. 2 e questo è il problema che hai menzionato, che non sembra essere il problema Qui. Onestamente penso che questo problema sia nuovo. –