title: WPF Please Wait Dialog
body: <p>I'm developing a WPF desktop application in c# 4.0 which has to handle a lot of long-running operations (loading data from the DB, calculating simulations, optimizing routes, etc.).</p>
  
  <p>When these long-running operations run in the background I want to show a Please-Wait dialog. When the Please-Wait dialog is shown the application should be locked, but to just disable the application window isn't a good idea because all the DataGrids would lose their status (<code>SelectedItem</code>).</p>
  
  <p>What I have so far works but there are some problems:
  A new WaitXUI is created using the Create-factory method. The Create method expects caption text and a refernce to the host control that should be locked. The Create method sets the StartupLocation of the window, the caption text and the host to lock:</p>
  
  <pre><code>WaitXUI wait = WaitXUI.Create("Simulation running...", this);
  wait.ShowDialog(new Action(() =&gt;
  {
      // long running operation
  }));
  </code></pre>
  
  <p>With the overloaded ShowDialog method the WaitXUI can then be displayed. The ShowDialog overload does expect an Action which wraps the long running operation.</p>
  
  <p>In the ShowDialog overload I just start the Action in its own thread and then disable the host control (set Opacity to 0.5 and set IsEnabled to false) and call ShowDialog of the base class.</p>
  
  <pre><code>public bool? ShowDialog(Action action) 
      {
      bool? result = true;
  
      // start a new thread to start the submitted action
      Thread t = new Thread(new ThreadStart(delegate()
      {
          // start the submitted action
          try
          {
              Dispatcher.UnhandledException += Dispatcher_UnhandledException;
              Dispatcher.Invoke(DispatcherPriority.Normal, action);
          }
          catch (Exception ex)
          {
              throw ex;
          }
          finally
          {
              // close the window
              Dispatcher.UnhandledException -= Dispatcher_UnhandledException;
              this.DoClose();
          }
      }));
      t.Start();
  
      if (t.ThreadState != ThreadState.Stopped)
      {
          result = this.ShowDialog();
      }
      return result;
  }
  
  private new bool? ShowDialog() 
  {
      DisableHost();
      this.Topmost = true;
      return base.ShowDialog();
  }
  
  private void DisableHost()
  {
      if (host != null)
      {
          host.Dispatcher.Invoke(new Action(delegate()
          {
              this.Width = host.Width - 20;
              host.Cursor = Cursors.Wait;
              host.IsEnabled = false;
              host.Opacity = 0.5;
          }));
      }
  }
  </code></pre>
  
  <p>Here are the problems with this:</p>
  
  <ul>
  <li>Disabling the host control results in lost of status information (SelectedItems...)</li>
  <li>The WaitXUI sometimes is shown for only some milliseconds when the thread ends a few ms after the WaitXUI is shown</li>
  <li>Sometimes the dialog doesn't appear at all although the thread is still running</li>
  </ul>
  
  <p>These are the main problems which come to my mind at the moment. How can this concept be improved, or what other methods can be employed to address this problem?</p>
  
  <p>Thanks in advance!</p>