title: Windows Forms: UI threads flow with Show() and ShowDialog()
body: <p>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:</p>
  
  <p><img src="https://i.stack.imgur.com/a7aJ3.png" alt="Continuos progress window"></p>
  
  <p>In solution tree it is situated on the same level as the <strong>Main Window</strong>:</p>
  
  <p><img src="https://i.stack.imgur.com/HiN43.png" alt="Windows forms solution tree"></p>
  
  <p>The simplest working approach to show continuous progress while doing something is the following code. It <strong>does work</strong>:</p>
  
  <pre><code>//This method works
  private void DoSomeBackgroundStuffWithShow()
  {
      ContinuousProgressWindow continuousProgressWindow = 
          new ContinuousProgressWindow();
      BackgroundWorker backgroundWorker = new BackgroundWorker();
      backgroundWorker.DoWork += (sender, arguments) =&gt;
      {
          //Do some  stuff for 4 seconds
          Thread.Sleep(4000);
      };
      backgroundWorker.RunWorkerCompleted += (sender, arguments) =&gt;
      {
          //Window is closed when needed. Great!
          continuousProgressWindow.Dispose(); 
      };
      continuousProgressWindow.Show(this);
      backgroundWorker.RunWorkerAsync();
  }
  </code></pre>
  
  <p>But I need this window to appear <strong>topmost</strong> and block its parent while working. The following code is quite similar, and it does not work - the dialog is shown, but <strong>never closed</strong>:</p>
  
  <pre><code>//This method DOES NOT WORK
  private void DoSomeBackgroundStuffWithShowDialog()
  {
      ContinuousProgressWindow continuousProgressWindow =
          new ContinuousProgressWindow();
      BackgroundWorker backgroundWorker = new BackgroundWorker();
      backgroundWorker.DoWork += (sender, arguments) =&gt;
      {
          //Do some important stuff for 4 seconds
          Thread.Sleep(4000);
      };
      backgroundWorker.RunWorkerCompleted += (sender, arguments) =&gt;
      {
          //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();
  }
  </code></pre>
  
  <p>Then, I realize the problem is about UI threads flow: when the progress window is ran as a dialog, <code>MainWindow</code> thread is frozen and it cannot be invoked by <code>BackgroundWorker</code> in <code>RunWorkerCompleted</code> delegate to close the dialog.</p>
  
  <p><strong>What is the simplest solution to make it work as wanted?</strong></p>