我的性能问题非常糟糕。我目前正在开发一个多窗口应用程序,但当我关闭其中一个窗口时,没有内存被释放。
甚至还有我在代码中实例化的控件,在我使用它们之后,我为它们的字段分配了null,但没有。 GC拒绝收集控件,尽管不再有参考。
Google搜索该问题会将我带到Application.Exit
和Dispatcher.ShutdownStarted
,但它们无法解决我的问题,导致应用程序继续运行。
我做了一个小样本来向你展示我的问题:
MainPage.xaml
<Window x:Class="FinalizerSampleProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FinalizerSampleProject"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Content="Get rid of the custom control!" Grid.Row="1" Click="Button_Click" x:Name="DummyButton" />
</Grid>
</Window>
MainPage.xaml.cs
using System;
using System.Windows;
namespace FinalizerSampleProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private CustomControl control = new CustomControl();
public MainWindow()
{
InitializeComponent();
LayoutRoot.Children.Add(control);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (control != null)
{
LayoutRoot.Children.Remove(control);
control = null;
DummyButton.Content = "Show how many instances of CustomControl still exist.";
GC.Collect();
}
else
{
MessageBox.Show(CustomControl.InstanceCounter.ToString());
}
}
}
}
CustomControl.xaml
<UserControl x:Class="FinalizerSampleProject.CustomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Background="LightGreen">
<TextBlock Text="Hi, I'm a custom control!"/>
</UserControl>
CustomControl.xaml.cs
using System.Windows.Controls;
namespace FinalizerSampleProject
{
/// <summary>
/// Interaction logic for CustomControl.xaml
/// </summary>
public partial class CustomControl : UserControl
{
public static int InstanceCounter = 0;
public CustomControl()
{
InstanceCounter++;
InitializeComponent();
}
~CustomControl()
{
InstanceCounter--;
}
}
}
如果你试试,你会发现这个计数器每次看起来都是“一”。我不知道如何摆脱那个对象实例。
答案 0 :(得分:1)
注意:此答案仅适用于有关WinForms UserControl的问题。
您的自定义控件可能会按照应有的方式处理和“释放”。只是你的终结器代码没有被调用,因为当UserControl被释放时它告诉垃圾收集器不要调用它的终结器。
这是禁止调用终结函数的标准Dispose
实现:
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
该代码来自System.ComponentModel.Component
。您的CustomControl
课程来自UserControl
。
行GC.SuppressFinalize(this)
是阻止你的计数器减少的原因。不过不用担心,实例会被处理(并由GC收集)。
请改为尝试:
public static int InstanceCounter = 0;
private bool disposed;
public CustomControl()
{
InstanceCounter++;
InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
InstanceCounter--;
this.disposed = true;
}
}