закрытие окна WPF не запускает уничтожение - PullRequest
1 голос
/ 31 января 2012

Предположим следующий сценарий: в реализации MVVM есть окно WPF.Имея следующий код в своем коде за файлом (на самом деле я знаю, что лучше использовать первый подход ViewModel, но на этом этапе достаточно использовать View First):

public MainWindow()
{
    InitializeComponent();
    this.DataContext = MainWindowViewModel.GetInstance();
}

в конструкторе

ClassStartingWorkerThread instance;
MainWindowViewModel()
{
    instance = new ClassStartingWorkerThread();
}

Я инициализирую экземпляр класса, который запускает Thread по конструкции, как показано ниже:

ClassStartingWorkerThread()
{
    StartThread();
}

private Thread mEventRequestingThread = null;
private void StartThread()
{
    ThreadStart cDelegate = new ThreadStart(EventListening);
    mEventRequestingThread = new Thread(cDelegate);
    mEventRequestingThread.Start();
}

Этот класс реализует интерфейс IDisposable.Поэтому я вызываю мой метод Dispose вручную для Destruction так:

~ClassStartingWorkerThread()
{
    Dispose(false);
}

public void Dispose()
{
    mEventRequestingThread.Abort();
}

По крайней мере, вы должны знать: я запускаю свое приложение из Visual Studio.Теперь я закрываю окно UI и ожидаю, что моя рутина уничтожит созданные объекты.Но Visual Studio не возвращается в режим «редактирования» и остается в режиме «отладки».

Я думаю, что-то не так с моей подпрограммой потока, но мне интересно, почему ни деструктор MainWindow, ниВызывается деструктор MainWindowViewModel.

Это приводит к вопросу о том, как я могу вручную запустить процедуру уничтожения и сказать моему рабочему потоку, который на самом деле блокирует это, остановиться?

Заранее спасибоТомас

Ответы [ 2 ]

3 голосов
/ 31 января 2012

Проблема в том, что ваш деструктор ~ClassStartingWorkerThread() никогда не вызывается сборщиком мусора. Экземпляр этого класса не может быть собран мусором, поскольку исполняющий поток ссылается на него через делегат ThreadStart. Как правило, вы никогда не должны полагаться на деструктора, призванного вообще. См. MSDN на C # Деструкторы .

В вашем случае просто установите для свойства Thread.IsBackground значение true. Это приведет к автоматическому завершению потока при завершении работы приложения.

Если вам действительно требуется ручное управление завершением вашего рабочего потока, вы не должны прерывать его, а вместо этого позволить ему ждать (или циклически проверять) некоторого WaitHandle и завершать себя, когда WaitHandle сигнализируется. Когда дело доходит до завершения, Установите WaitHandle в вашем основном потоке, возможно, в обработчике Window.Closing.

1 голос
/ 31 января 2012

Я согласен с ответом Клеменса.

Всего две точки:

  1. Удалить вашу ветку в событии closewindow. Я не знаю названий событий в WPF, но должен быть один, который вызывается при закрытии окна. Используйте это.

  2. При удалении тем вы всегда должны использовать другие методы, кроме Abort (). Отправьте сигнал этому потоку, чтобы он был проинформирован о том, что окно скоро будет закрыто, и пусть поток мирно завершит свое выполнение самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...