title: Updating the UI from events raised by a background thread
body: <p>My WPF application launches long running functions on background threads, typically via a button click/command, e.g.</p>
  
  <pre><code>StartCommand = new RelayCommand(async o =&gt; await StartAsync(), o =&gt; true);
  
  ...
  
  private async Task StartAsync()
  {
      await Task.Run(() =&gt; LongRunningFunction());
  }
  </code></pre>
  
  <p>These long running functions raise various events to report progress to the user, update UI values, etc. The view-model handles such events and updates bound properties, e.g.:</p>
  
  <pre><code>private void LongRunningProcessProgressChanged(object sender, ProgressEventArgs e)
  {
      StatusMessageText = string.Format("Progress {0}%", e.Progress);
  }
  </code></pre>
  
  <p>Most of the time this works fine but occasionally I get the usual exception about updating the UI from a background thread ("The calling thread cannot access this object because a different thread owns it")), so I have to wrap the code in a <code>Dispatcher.Invoke(...)</code>. I haven't really spotted a pattern as to when I do or don't have to do this, so can anyone shed some light on it?</p>
  
  <p>To be honest I'm surprised that the above code works at all. A breakpoint confirms that these event handlers run on a worker thread, not the UI thread, so why don't I see the exception all the time? Is it something to do with the type of property being updated?</p>
  
  <p><strong>Edit</strong> People are proposing answers to a problem which I am already aware of. Reading my question again I might have confused readers with the part "Most of the time this works fine but occasionally I get the usual exception". I didn't mean that it's an intermittent problem - what I really meant was that some of my VMs don't have a problem updating bound properties within their respective progress event handler, while other VMs do. I suspect it has something to do with the property type, e.g. updating a string property works but not an ObservableCollection. </p>
  
  <p>My question was more of a curiosity thing, i.e. why some bound properties are okay with being updated from a b/g thread while others aren't.</p>