title: wpf Exception on ShowDialog for a progress dialog with backgroundworker
body: <p>I followed an example I saw online and create a progress dialog (code below), and in the main thread, I call </p>
  
  <pre><code>  ProgressDialog pd = new ProgressDialog("Loading File: ", VCDFileName);
    pd.Owner = Application.Current.MainWindow;
    pd.WindowStartupLocation = WindowStartupLocation.CenterOwner;
    ModuleHierarchyVM.TopLevelModules.Clear();
  
  
    VCDData TempVCDOutput = null;
    Action handler = delegate
    {
        VCDParser.ParseVCDFileForAllPorts(VCDFileName, this, pd.Worker, ModuleHierarchyVM.TopLevelModules, out TempVCDOutput);
    };
  
    pd.SetBGWorkerDelegate(handler);
    pd.ShowDialog();
  </code></pre>
  
  <p>I think that the error is happening in the function being passed to the delegate. I think I'm getting two exceptions ( one on each thread maybe?) the first one says,</p>
  
  <p>TargetInvocationException was unhandled. Exception has been thrown by the target of an invocation.</p>
  
  <p>I think this exception is being thrown by the UI thread because sometimes breakpoints are hit inside the function passed to the delegate before the exception is shown and sometimes they are not.</p>
  
  <p>then after hitting f5 for a while, and going through the many break points in the function being done in the background,</p>
  
  <p>I eventually come back to the UI thread and pd.ShowDialog() and get this exception:</p>
  
  <p>InvalidOperationException was unhandled. ShowDailog can be called only on hidden windows.</p>
  
  <p>I put a bunch of try catch blocks to try to catch the exception if it was happening inside the function being passed to the delegate but I didn't catch it. It doesn't seem to </p>
  
  <p>Code from Progress Dialog</p>
  
  <pre><code>  public partial class ProgressDialog : Window
    {
      BackgroundWorker _worker;
      public BackgroundWorker Worker
      {
        get { return _worker; }
      }
  
  
      public string MainText
      {
        get { return MainTextLabel.Text; }
        set { MainTextLabel.Text = value; }
      }
  
      public string SubText
      {
        get { return SubTextLabel.Text; }
        set { SubTextLabel.Text = value; }
      }
  
  
  
      public bool IsCancellingEnabled
      {
        get { return CancelButton.IsVisible; }
        set { CancelButton.Visibility = value ? Visibility.Visible : Visibility.Collapsed; }
      }
  
  
      private bool _Cancelled = false;
      public bool Cancelled
      {
        get { return _Cancelled; }
      }
  
      private Exception error = null;
      public Exception Error
      {
        get { return error; }
      }
  
  
      private object result = null;
      public object Result
      {
        get { return result; }
      }
  
  
      /// &lt;summary&gt;
      /// Represents the method that will handle the DoWork event from the backgroundowkrker
      /// &lt;/summary&gt;
      private Action workerCallback;
  
      private object BackgroundWorkerArgument;
  
  
      public ProgressDialog(string MainText, string SubText)
        : this()
      {
        this.MainText = MainText;
        this.SubText = SubText;
      }
  
  
      public ProgressDialog()
      {
        InitializeComponent();
  
        this.Loaded += new RoutedEventHandler(ProgressDialog_Loaded);
  
        _worker = new BackgroundWorker();
        _worker.WorkerReportsProgress = true;
        _worker.WorkerSupportsCancellation = true;
  
  
        _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
        _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
        _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
        Closing += new CancelEventHandler(ProgressDialog_Closing);
      }
  
      void ProgressDialog_Loaded(object sender, RoutedEventArgs e)
      {
        _worker.RunWorkerAsync(BackgroundWorkerArgument);
      }
  
      void ProgressDialog_Closing(object sender, CancelEventArgs e)
      {
        //if progress dialog is open
        if (DialogResult == null)
        {
          MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure you wish to cancel?",
             "Confirmation", System.Windows.MessageBoxButton.YesNo);
          if (messageBoxResult == MessageBoxResult.Yes)
          {
            if (_worker.IsBusy)
            {
              //notifies the async thread that a cancellation has been requested.
              _worker.CancelAsync();
            }
            DialogResult = false;
          }
          else
          {
  
            e.Cancel = true;
          }
        }
        else
        {
  
          if (_worker.IsBusy)
          {
            //notifies the async thread that a cancellation has been requested.
            _worker.CancelAsync();
          }
        }
  
      }
  
  
  
  
      void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
        if (!Dispatcher.CheckAccess())
        {
          //run on UI thread
          RunWorkerCompletedEventHandler handler = _worker_RunWorkerCompleted;
          Dispatcher.Invoke(handler, null, DispatcherPriority.SystemIdle, new object[] { sender, e });
          return;
        }
        else
        {
          if (e.Error != null)
          {
            error = e.Error;
          }
          else if (!e.Cancelled)
          {
            //assign result if there was neither exception nor cancel
            result = e.Result;
          }
          ProgressBar.Value = ProgressBar.Maximum;
          CancelButton.IsEnabled = false;
  
  
          //set the dialog result, which closes the dialog
          if (DialogResult == null)
          {
            if (error == null &amp;&amp; !e.Cancelled)
            {
              DialogResult = true;
            }
            else
            {
              DialogResult = false;
            }
          }
        }
  
      }
  
      void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
      {
        if (!Dispatcher.CheckAccess())
        {
          //run on UI thread
          ProgressChangedEventHandler handler = _worker_ProgressChanged;
          Dispatcher.Invoke(handler, null, DispatcherPriority.SystemIdle, new object[] { sender, e });
          return;
        }
        else
        {
          if (e.ProgressPercentage != int.MinValue)
          {
            ProgressBar.Value = e.ProgressPercentage;
          }
  
        }
  
      }
  
      void _worker_DoWork(object sender, DoWorkEventArgs e)
      {
        try
        {
          if ((_worker.CancellationPending == true))
          {
            //cancel the do work event
            e.Cancel = true;
          }
          else
          {
            // Perform a time consuming operation and report progress.
            workerCallback();
          }
  
        }
        catch (Exception)
        {
          //disable cancelling and rethrow the exception
          Dispatcher.BeginInvoke(DispatcherPriority.Normal,
            new Action(delegate { CancelButton.SetValue(Button.IsEnabledProperty, false); }), null);
          throw;
        }
      }
  
  
  
  
      public void SetBGWorkerDelegate(Action workHandler)
      {
        SetBGWorkerDelegate(null, workHandler);
      }
      public void SetBGWorkerDelegate(object argument, Action workHandler)
      {
        //store reference to callback handler and launch worker thread
        workerCallback = workHandler;
        BackgroundWorkerArgument = argument;
  
  
  
      }
  
  
      private void CancelButton_Click(object sender, RoutedEventArgs e)
      {
        MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show("Are you sure you wish to cancel?", 
          "Confirmation", System.Windows.MessageBoxButton.YesNo);
        if (messageBoxResult == MessageBoxResult.Yes)
        {
          if (_worker.IsBusy)
          {
            //notifies the async thread that a cancellation has been requested.
            _worker.CancelAsync();
          }
          DialogResult = false;        
        }
  
  
      }
    }
  }
  </code></pre>