Сборщик мусора не удаляет объект. Мне необходимо чтобы 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 ? |