inva
inva

Reputation: 761

closing WPF Window does not start destruction

Assume following scenario: There is a WPF window, within a MVVM implementation. Having following code in it's code behind file (acutally I know I rather should use ViewModel first approach, but using View First is enough at this stage):

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

within the constructor of

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

I initialize an instance of a class which starts a Thread on construction like shown below:

ClassStartingWorkerThread()
{
    StartThread();
}

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

This class implements the IDisposable interface. Therefore I call my Dispose method manually on Destruction like this:

~ClassStartingWorkerThread()
{
    Dispose(false);
}

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

At least you shall know: I start my application from Visual Studio. Now, I'm closing my UI Window and would expect my routine to destruct created objects. But the the Visual Studio does not go back into "edit" mode and stays in "debug" mode.

I guess there's something wrong with my thread routine, but I'm wondering why neither the MainWindow destructor nor the MainWindowViewModel destructor is called.

This leads to the question on how I can manually start the destruction routine and tell my worker thread, which actually seems to block this, to stop?

Thanks in advance, Thomas

Upvotes: 1

Views: 4353

Answers (2)

Clemens
Clemens

Reputation: 128087

The problem is that your destructor ~ClassStartingWorkerThread() is never called by the garbage collector. The instance of that class cannot be garbage-collected since the executing thread references it via the ThreadStart delegate. Generally you should never rely on a destructor beeing called at all. See the MSDN on C# Destructors.

In your case simply set the Thread.IsBackground property to true. This will make the thread terminate automatically when the application shuts down.

If you really have to have manual control over the termination of your worker thread, you shouldn't abort it, but instead let it wait for (or cyclically check) some WaitHandle and terminate itself when the WaitHandle is signalled. When it comes to termination, Set the WaitHandle in your main thread, perhaps in a Window.Closing event handler.

Upvotes: 3

Al Kepp
Al Kepp

Reputation: 5980

I agree with Clemens' answer.

Just two points:

  1. Delete your thread in a closewindow event. I don't know the names of events in WPF, but there must be one which is called when closing the window. Use it.

  2. When deleting threads, you should always prefer some other methods than Abort(). Send a signal to that thread to let it be informed that window is about to be closed and let the thread peacefully ends its execution on its own.

Upvotes: 1

Related Questions