我的应用程序是由MVVM设计的。
主窗口是MainWindow.xaml,如下所示。主窗口有两个用户控件。
顺便说一句,当更改viewmodel的属性时,将在运行时动态创建usercontrol。
但似乎我的应用程序存在内存泄漏。
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 is related to MainWindowViewModel.cs. According to ViewType property, each usercontrol is created dynamically in run time.
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 has uc1ViewModel.cs. UserControl2.xaml has uc2ViewModel.cs as below.
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");
}
}
MainViewModel.cs的ChangeView函数每秒更改一次ViewType属性。
更改ViewType的属性时,将ui1ViewModel创建为新实例。如果下次创建ui1ViewModel的实例,我希望ui1ViewModel的旧实例会被垃圾收集器删除。
但是,当进行大量测试时,看起来应用程序有内存泄漏。
我检查了ui1ViewModel的析构函数
然后在析构函数中键入Debug.WriteLine(“Call Destructor”)。但它不会每次都调用。
当我强制调用GC.Collect()时,将调用ui1ViewModel的析构函数,并减少应用程序的内存大小。
所以,我的问题是
在这种情况下可以强制调用GC.collect()吗?还是您有其他解决此问题的方法?
最佳答案
我也不认为这是内存泄漏:
A correctly-written program cannot assume that finalizers will ever run.
Raymond Chen对于垃圾收集对人们的误解有一个很好的解释:
http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx
我将永远记住这一点:
Garbage collection is simulating a computer with an infinite amount of memory. The rest is mechanism.
关于c# - 用户控件在运行时动态创建,但存在内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8033112/