Сборщик мусора не удаляет объект - C#

Узнай цену своей работы

Формулировка задачи:

Сборщик мусора не удаляет объект. Мне необходимо чтобы GC его удалил, но этого не происходит. Привожу предельно упрощенный код моей программы. Простая форма XAML с лейблом и кнопкой, нажатие кнопки запускает уничтожение объекта:
<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>
Класс foo имеет единственное поле A, которое генерирует событие NotifyPropertyChange, запускается новый поток, в нем поле A раз в секунду обновляется, метод Dispose останавливает поток.
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()
        {

        }
 
    }
Ну и код класса окна. Здесь мы привязываем созданный объект класса foo, привязываем лейбл на форме к нему. При нажатии на кнопку, удаляем привязку, обнуляем ссылку на объект. После этого, принудительно просим GC почистить.
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();         
        }
    
    }
При данных условиях финализатор ~foo() не вызывается, что говорит о том, что сборщик мусора объект не удаляет. Однако, если закоментить привязку, все будет работать как надо. Что нужно сделать, чтобы сборщик мусора удалил объект класса foo ?

Решение задачи: «Сборщик мусора не удаляет объект»

textual
Листинг программы
bg.Source = fooInst; // <--- тут ссылка на объект все еще жива

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.769 из 5
Похожие ответы