Сборщик мусора не удаляет объект - 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; // <--- тут ссылка на объект все еще жива
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д