Сборщик мусора не удаляет объект - C#
Формулировка задачи:
Сборщик мусора не удаляет объект. Мне необходимо чтобы GC его удалил, но этого не происходит.
Привожу предельно упрощенный код моей программы.
Простая форма XAML с лейблом и кнопкой, нажатие кнопки запускает уничтожение объекта:
Класс foo имеет единственное поле A, которое генерирует событие NotifyPropertyChange,
запускается новый поток, в нем поле A раз в секунду обновляется, метод Dispose останавливает поток.
Ну и код класса окна. Здесь мы привязываем созданный объект класса foo, привязываем лейбл на форме к нему.
При нажатии на кнопку, удаляем привязку, обнуляем ссылку на объект. После этого, принудительно просим GC почистить.
При данных условиях финализатор ~foo() не вызывается, что говорит о том,
что сборщик мусора объект не удаляет. Однако, если закоментить привязку, все будет работать как надо.
Что нужно сделать, чтобы сборщик мусора удалил объект класса foo ?
<Window x:Class="Disposer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Name="TestLabel" Margin="0,0,325,189"></Label>
<Button Margin="203,12,72,216" Click="Button_Click"></Button>
</Grid>
</Window>
public class foo:INotifyPropertyChanged, IDisposable
{
Thread thr;
volatile bool bThrEnabled = true;
public event PropertyChangedEventHandler PropertyChanged;
int t = 0;
protected void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
private string _a;
public string A
{
get
{
return _a;
}
set
{
_a = value;
RaisePropertyChanged("A");
}
}
public foo()
{
thr = new Thread(ThreadFunc);
(thr).Start();
}
public void ThreadFunc()
{
while (bThrEnabled)
{
A = (t++).ToString();
Thread.Sleep(1000);
if (!bThrEnabled) break;
}
PropertyChanged = null;
A = null;
_a = null;
}
public void Dispose()
{
bThrEnabled = false;
while (thr.IsAlive)
Thread.Sleep(1000);
}
~foo()
{
}
}public partial class MainWindow : Window
{
foo fooInst;
public MainWindow()
{
InitializeComponent();
fooInst = new foo();
Binding bg = new Binding();
bg.Path = new PropertyPath("A");
bg.Source = fooInst;
BindingOperations.SetBinding(TestLabel, Label.ContentProperty, bg);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
fooInst.Dispose();
BindingOperations.ClearAllBindings(TestLabel);
BindingOperations.ClearBinding(TestLabel, Label.ContentProperty);
TestLabel.DataContext = null;
fooInst = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}Решение задачи: «Сборщик мусора не удаляет объект»
textual
Листинг программы
bg.Source = fooInst; // <--- тут ссылка на объект все еще жива