Мое приложение разработано MVVM.
Главное окно - MainWindow.xaml, как показано ниже. Главное окно имеет два пользовательских элемента управления.
Кстати, usercontrol создается динамически во время выполнения, когда изменяется свойство viewmodel.
Но, похоже, у моего приложения есть утечка памяти.
MainWindow.xaml
<Window x:Class="InstanceTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InstanceTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainWindowViewModel x:Key="MainWindowViewModel" />
<DataTemplate x:Key="UD1">
<ContentControl>
<local:UserControl1></local:UserControl1>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="UD2">
<ContentControl>
<local:UserControl2></local:UserControl2>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="contentsTemplate">
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ViewType}" Value="1">
<Setter Property="ContentTemplate" Value="{DynamicResource UD1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ViewType}" Value="2">
<Setter Property="ContentTemplate" Value="{DynamicResource UD2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</Window.Resources>
<Grid DataContext="{StaticResource MainWindowViewModel}">
<StackPanel>
<Button Height="30" Command="{Binding ChangeViewCommand}">ChangeView</Button>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource contentsTemplate}" />
</StackPanel>
</Grid>
MainWindow.xaml связан с MainWindowViewModel.cs.
Согласно свойству ViewType каждый пользовательский элемент управления создается динамически во время выполнения.
public class MainWindowViewModel : ViewModelBase
{
private string viewType;
public string ViewType
{
get { return viewType; }
set
{
viewType = value;
base.RaisePropertyChanged(() => this.ViewType);
}
}
public MainWindowViewModel()
{
ChangeViewCommand = new RelayCommand(ChangeView);
}
public ICommand ChangeViewCommand { get; private set; }
private void ChangeView(object o)
{
int aa = 1000;
while (aa > 0)
{
System.Threading.Thread.Sleep(1000);
System.Windows.Forms.Application.DoEvents();
if (ViewType == "1")
ViewType = "2";
else
ViewType = "1";
aa--;
//GC.Collect();
}
}
}
UserControl1.xaml
<UserControl.Resources>
<local:uc1ViewModel x:Key="uc1ViewModel" />
</UserControl.Resources>
<Grid DataContext="{StaticResource uc1ViewModel}">
<StackPanel>
<TextBlock FontSize="30" Text="{Binding TextExample}"></TextBlock>
<Image Source="/InstanceTest;component/Images/sample.jpg" />
</StackPanel>
</Grid>
UserControl1.xaml имеет uc1ViewModel.cs. UserControl2.xaml имеет uc2ViewModel.cs, как показано ниже.
public class uc1ViewModel : ViewModelBase
{
private string textExample;
public string TextExample
{
get { return textExample; }
set
{
textExample = value;
base.RaisePropertyChanged(() => this.TextExample);
}
}
public uc1ViewModel()
{
TextExample = "UD1...";
}
~uc1ViewModel()
{
Debug.WriteLine("Call Destructor");
}
}
Функция ChangeView файла MainViewModel.cs меняет свойство ViewType каждую секунду.
При изменении свойства ViewType, ui1ViewModel создается как новый экземпляр. Если экземпляр ui1ViewModel будет создан в следующий раз, я ожидаю, что старый экземпляр ui1ViewModel будет удален сборщиком мусора.
Но, похоже, приложение испытывает утечку памяти при тестировании несколько раз.
Я проверил деструктор ui1ViewModel
и введите Debug.WriteLine ("Call Destructor") в деструкторе. но он не звонит каждый раз.
Когда я вызываю GC.Collect () принудительно, вызывается деструктор ui1ViewModel и уменьшает объем памяти приложения.
Итак, мой вопрос
Могу ли я вызвать GC.collect () принудительно в этом случае? или у вас есть другой способ решить эту проблему?