Windows Forms: UI threads flow with Show() and ShowDialog()

Viewed 2496

While developing a solution on Windows Forms I went into a routine of showing continuous progress to user. I implemented simple dummy window with continuous progress bar:

Continuos progress window

In solution tree it is situated on the same level as the Main Window:

Windows forms solution tree

The simplest working approach to show continuous progress while doing something is the following code. It does work:

//This method works
private void DoSomeBackgroundStuffWithShow()
{
    ContinuousProgressWindow continuousProgressWindow = 
        new ContinuousProgressWindow();
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += (sender, arguments) =>
    {
        //Do some  stuff for 4 seconds
        Thread.Sleep(4000);
    };
    backgroundWorker.RunWorkerCompleted += (sender, arguments) =>
    {
        //Window is closed when needed. Great!
        continuousProgressWindow.Dispose(); 
    };
    continuousProgressWindow.Show(this);
    backgroundWorker.RunWorkerAsync();
}

But I need this window to appear topmost and block its parent while working. The following code is quite similar, and it does not work - the dialog is shown, but never closed:

//This method DOES NOT WORK
private void DoSomeBackgroundStuffWithShowDialog()
{
    ContinuousProgressWindow continuousProgressWindow =
        new ContinuousProgressWindow();
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += (sender, arguments) =>
    {
        //Do some important stuff for 4 seconds
        Thread.Sleep(4000);
    };
    backgroundWorker.RunWorkerCompleted += (sender, arguments) =>
    {
        //None of the following work for "ShowDialog() method"
        //Ran with debugger - breakpoints not hit!
        continuousProgressWindow.DialogResult = DialogResult.OK;
        continuousProgressWindow.Close();
        continuousProgressWindow.Dispose();
    };
    continuousProgressWindow.ShowDialog(this);
    backgroundWorker.RunWorkerAsync();
}

Then, I realize the problem is about UI threads flow: when the progress window is ran as a dialog, MainWindow thread is frozen and it cannot be invoked by BackgroundWorker in RunWorkerCompleted delegate to close the dialog.

What is the simplest solution to make it work as wanted?

2 Answers
Related