1

I have been trying to figure out a problem with a background load I do on startup. The application runs totally fine but when its closed, it hangs forever. I assumed this was a threading issue. I have narrowed it down to the following code. I have been googling around but not come across anything which fits the problem I am having, can anybody elaborate on the thread safety here?

I assumed that considering the loading screen is closed when the worker is completed ( m_LoaderWindow.Close(); ) that it wouldn't be problematic.

This code doesn't work

            m_LoaderWindow = new LoadingWindow();

            m_BackgroundWorker = new BackgroundWorker();
            OnProgressDelegate = m_BackgroundWorker.ReportProgress;
            m_BackgroundWorker.WorkerReportsProgress = true;
            m_BackgroundWorker.ProgressChanged += (object sender, ProgressChangedEventArgs arg) =>
            {
                LoaderWindow.Context.Progress = arg.ProgressPercentage;
            };

            m_BackgroundWorker.DoWork += MBackgroundWorkerOnDoWork;
            m_BackgroundWorker.RunWorkerCompleted += MBackgroundWorkerOnRunWorkerCompleted;
            m_BackgroundWorker.RunWorkerAsync();

            m_LoaderWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            m_LoaderWindow.Owner = Application.Current.MainWindow;
            m_LoaderWindow.ShowDialog();

This code works (but obviously no loading screen)

            m_BackgroundWorker = new BackgroundWorker();
            OnProgressDelegate = m_BackgroundWorker.ReportProgress;
            m_BackgroundWorker.WorkerReportsProgress = true;
            m_BackgroundWorker.ProgressChanged += (object sender, ProgressChangedEventArgs arg) =>
            {
                LoaderWindow.Context.Progress = arg.ProgressPercentage;
            };

            m_BackgroundWorker.DoWork += MBackgroundWorkerOnDoWork;
            m_BackgroundWorker.RunWorkerCompleted += MBackgroundWorkerOnRunWorkerCompleted;
            m_BackgroundWorker.RunWorkerAsync();

Here is the worker completed code

    private void MBackgroundWorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
    {
        Application.Current.Dispatcher.Invoke(new Action(() =>
        {   
            m_LoaderWindow.Close();
        }));
    }
2
  • 2
    FYI, the RunWorkerCompleted event will fire on the UI thread. Therefore you do not need to use Dispatcher.Invoke in order to close your loader window. Commented Feb 20, 2015 at 14:58
  • Thanks, you are right. Unfortunately still doesn't solve the problem :(. Commented Feb 20, 2015 at 14:59

1 Answer 1

1

Ok it wasn't related to anything with the threading. In my ViewModel I was doing this:

public LoadingWindow m_LoaderWindow = new LoadingWindow();

And then I was allocating it AGAIN in the main thread.

Although I can't explain why this causes it to hang on exit?

Sign up to request clarification or add additional context in comments.

2 Comments

Just ran in to this myself a day or two ago. Creating a new window in WPF, even if you never show it, will prevent the Dispatcher from shutting down if the window has not been closed. Every window that is newed up must have .Close() called on it (explicitly or implicitly via user action like clicking the X in the corner).
One of those gotchas that you have to battle through :) thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.