title: Is BackgroundWorker the only way to keep a WCF/WPF application responsive?
body: <p>Client/server desktop application using C#, WCF, WPF.  Since pretty much every action is going to require a trip to the server (list/create/save/delete/etc), every action has the potential to freeze the entire UI.  Here's an example of a naive implementation with a call to <code>service.GetAll()</code> which could take a "long" time (more than a few hundred milliseconds):</p>
  
  <pre><code>private void btnRefresh_Click(object sender, RoutedEventArgs e)
  {
      vm.Users.Clear();
      foreach (var user in service.GetAllUsers())
          vm.Users.Add(user);
  }
  </code></pre>
  
  <p>(Aside: I'd love to know why <a href="http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx">List</a> has <code>AddRange</code> and <a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx">ObservableCollection</a> doesn't.)</p>
  
  <p><code>BackgroundWorker</code> to the rescue:</p>
  
  <pre><code>private void btnRefresh_Click(object sender, RoutedEventArgs e)
  {
      var worker = new BackgroundWorker();
  
      worker.DoWork += (s, e) =&gt;
      {
          Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = false; });
          e.Result = service.GetAllUsers();
      };
  
      worker.RunWorkerCompleted += (s, e) =&gt;
      {
          vm.Users.Clear();
          foreach (var user in (List&lt;UserDto&gt;)e.Result)
              vm.Users.Add(user);
          Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = true; });
      };
  
      worker.RunWorkerAsync();
  }
  </code></pre>
  
  <p>(Aside: code above has been simplified, but that's the gist of it.)</p>
  
  <p>The code using <code>BackgroundWorker</code> works exactly how I want it to.  The app remains responsive at all times, and the button is disabled for the duration of the call.  However, this means adding 15 lines to every possible action the user might make.</p>
  
  <p>Say it ain't so.</p>