title: c# MVVM InvalidOperationException on BackgroundWorker when using Dispatcher
body: <p>i'm currently facing an issue in C# WPF. I wrote an application, that generates long running reports in a background task. I am using prism with MVVM and trying to run the expensive background task with a Async ICommand implementation and a BackgroundWorker. But when i try to retrieve the resulting report </p>
  
  <pre><code>Report = asyncTask.Result;
  </code></pre>
  
  <p>i get an InvalidOperationException stating "The calling thread cannot access this object because a different thread owns it.". </p>
  
  <p>Yes, i have already tried to invoke a dispatcher (its the first thing you'll find on google, stackoverflow etc when you search for the exception message).  I have tried several variants like for instance:</p>
  
  <pre><code>Dispatcher.CurrentDispatcher.Invoke(() =&gt; Report = asyncTaks.Result);
  </code></pre>
  
  <p>or</p>
  
  <pre><code>Report.Dispatcher.Invoke(() =&gt; Report = asyncTask.Result);
  </code></pre>
  
  <p>but each time i get this exception.</p>
  
  <p>I am suspecting that the way i am calling the report UI is not adequate.</p>
  
  <p>The structure looks in brief as follows:</p>
  
  <pre><code>MainWindowViewModel
    -&gt; SubWindowCommand
        SubWindowViewModel
          -&gt; GenerateReportCommand
              ReportViewModel
                -&gt; GenerateReportAsyncCommand
                &lt;- Exception on callback
  </code></pre>
  
  <p>I am out of ideas, does anybody have a clue what i might be doing wrong?</p>
  
  <p>Below are a few code fragments</p>
  
  <hr>
  
  <p>Report Generator View Model:</p>
  
  <pre><code>public class ReportFlowDocumentViewModel : BindableBase
  {
      private IUnityContainer _container;
      private bool _isReportGenerationInProgress;
      private FlowDocument _report;
  
      public FlowDocument Report
      {
          get { return _report; }
          set
          {
              if (object.Equals(_report, value) == false)
              {
                  SetProperty(ref _report, value);
              }
          }
      }
  
      public bool IsReportGenerationInProgress
      {
          get { return _isReportGenerationInProgress; }
          set
          {
              if (_isReportGenerationInProgress != value)
              {
                  SetProperty(ref _isReportGenerationInProgress, value);
              }
          }
      }
  
  
      public ReportFlowDocumentView View { get; set; }
  
      public DelegateCommand PrintCommand { get; set; }
  
      public AsyncCommand GenerateReportCommand { get; set; }
  
      public ReportFlowDocumentViewModel(ReportFlowDocumentView view, IUnityContainer c)
      {
          _container = c;
  
          view.DataContext = this;
          View = view;
          view.ViewModel = this;
  
          InitializeGenerateReportAsyncCommand();
  
          IsReportGenerationInProgress = false;
      }
  
      private void InitializeGenerateReportAsyncCommand()
      {
          GenerateReportCommand = new CreateReportAsyncCommand(_container);
          GenerateReportCommand.RunWorkerStarting += (sender, args) =&gt;
          {
              IsReportGenerationInProgress = true;
  
              var reportGeneratorService = new ReportGeneratorService();
              _container.RegisterInstance&lt;ReportGeneratorService&gt;(reportGeneratorService);
          };
  
          GenerateReportCommand.RunWorkerCompleted += (sender, args) =&gt;
          {
              IsReportGenerationInProgress = false;
              var report = GenerateReportCommand.Result as FlowDocument;
              var dispatcher = Application.Current.MainWindow.Dispatcher;
  
              try
              {
                  dispatcher.VerifyAccess();
  
                  if (Report == null)
                  {
                      Report = new FlowDocument();
                  }
  
                  Dispatcher.CurrentDispatcher.Invoke(() =&gt;
                  {
                      Report = report;
                  });
  
              }
              catch (InvalidOperationException inex)
              {
                  // here goes my exception
              }
          };
      }
  
      public void TriggerReportGeneration()
      {
          GenerateReportCommand.Execute(null);
      }
  
  }
  </code></pre>
  
  <p>This is how i start the ReportView Window</p>
  
  <pre><code>var reportViewModel = _container.Resolve&lt;ReportFlowDocumentViewModel&gt;();
  
  View.ReportViewerWindowAction.WindowContent = reportViewModel.View;
  
  reportViewModel.TriggerReportGeneration();
  
  var popupNotification = new Notification()
  {
      Title = "Report Viewer",
  };
  ShowReportViewerRequest.Raise(popupNotification);
  </code></pre>
  
  <p>with </p>
  
  <pre><code>ShowReportViewerRequest = new InteractionRequest&lt;INotification&gt;();
  </code></pre>
  
  <p>AsyncCommand definition</p>
  
  <pre><code>public abstract class AsyncCommand : ICommand
  {
      public event EventHandler CanExecuteChanged;
      public event EventHandler RunWorkerStarting;
      public event RunWorkerCompletedEventHandler RunWorkerCompleted;
  
      public abstract object Result { get; protected set; }
      private bool _isExecuting;
      public bool IsExecuting
      {
          get { return _isExecuting; }
          private set
          {
              _isExecuting = value;
              if (CanExecuteChanged != null)
                  CanExecuteChanged(this, EventArgs.Empty);
          }
      }
  
      protected abstract void OnExecute(object parameter);
  
      public void Execute(object parameter)
      {
          try
          {
              onRunWorkerStarting();
  
              var worker = new BackgroundWorker();
              worker.DoWork += ((sender, e) =&gt; OnExecute(e.Argument));
              worker.RunWorkerCompleted += ((sender, e) =&gt; onRunWorkerCompleted(e));
              worker.RunWorkerAsync(parameter);
          }
          catch (Exception ex)
          {
              onRunWorkerCompleted(new RunWorkerCompletedEventArgs(null, ex, true));
          }
      }
  
      private void onRunWorkerStarting()
      {
          IsExecuting = true;
          if (RunWorkerStarting != null)
              RunWorkerStarting(this, EventArgs.Empty);
      }
  
      private void onRunWorkerCompleted(RunWorkerCompletedEventArgs e)
      {
          IsExecuting = false;
          if (RunWorkerCompleted != null)
              RunWorkerCompleted(this, e);
      }
  
      public virtual bool CanExecute(object parameter)
      {
          return !IsExecuting;
      }
  }
  </code></pre>
  
  <p>CreateReportAsyncCommand:</p>
  
  <pre><code>public class CreateReportAsyncCommand : AsyncCommand
  {
      private IUnityContainer _container;
  
      public CreateReportAsyncCommand(IUnityContainer container)
      {
          _container = container;
      }
  
      public override object Result { get; protected set; }
      protected override void OnExecute(object parameter)
      {
          var reportGeneratorService = _container.Resolve&lt;ReportGeneratorService&gt;();
          Result = reportGeneratorService?.GenerateReport();
      }
  
  }
  </code></pre>