title: Invalid cross-thread access with MVVM, ObservableCollection and Reactive Extensions (Rx)
body: <p>I'm currently working on Windows Phone applications and I would like to use Reactive Extensions to create asynchronism to have a better UI experience.</p>
  
  <p>I use the MVVM pattern: my View has a ListBox binded in my ViewModel to an ObservableCollection of Items. An Item has traditional properties like Name or IsSelected.</p>
  
  <pre><code>&lt;ListBox SelectionMode="Multiple" ItemsSource="{Binding Checklist, Mode=TwoWay}"&gt;
      &lt;ListBox.ItemTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;StackPanel Orientation="Horizontal"&gt;
                  &lt;CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/&gt;
              &lt;/StackPanel&gt;
          &lt;/DataTemplate&gt;
      &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
  </code></pre>
  
  <p>I instantiate my MainViewModel in App.xaml.cs:</p>
  
  <pre><code>public partial class App : Application
  {
      private static MainViewModel _viewModel = null;
  
      public static MainViewModel ViewModel
      {
          get
          {
              if (_viewModel == null)
                  _viewModel = new MainViewModel();
  
              return _viewModel;
          }
      }
  
      [...]
  }
  </code></pre>
  
  <p>And I load my data in MainPage_Loaded.</p>
  
  <pre><code>public partial class MainPage : PhoneApplicationPage
  {
     public MainPage()
      {
          InitializeComponent();
          this.DataContext = App.ViewModel;
          this.Loaded += new System.Windows.RoutedEventHandler(MainPage_Loaded);
      }
  
      private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
      {
          App.ViewModel.LoadData();
      }
  }
  </code></pre>
  
  <p>I load my data from my ViewModel (I'm going to move that code to the Model later):</p>
  
  <pre><code>public class MainViewModel : ViewModelBase
  {
      public ObservableCollection&lt;Item&gt; _checklist;
  
      public ObservableCollection&lt;Item&gt; Checklist
      {
          get
          {
              return this._checklist;
          }
          set
          {
              if (this._checklist != value)
              {
                  this._checklist = value;
              }
          }
      }
  
      private const string _connectionString = @"isostore:/ItemDB.sdf";
  
      public void LoadData()
      {
          using (ItemDataContext context = new ItemDataContext(_connectionString))
          {
              if (!context.DatabaseExists())
              {
                  // Create database if it doesn't exist
                  context.CreateDatabase();
              }
  
              if (context.Items.Count() == 0)
              {
                  [Read my data in a XML file for example]
  
                  // Save changes to the database
                  context.SubmitChanges();
              }
  
              var contextItems = from i in context.Items
                                  select i;
  
              foreach (Item it in contextItems)
              {
                  this.Checklist.Add(it);
              }
          }
      }
  
      [...]
  }
  </code></pre>
  
  <p>And it works fine, items are updated in the View.</p>
  
  <p>Now I want to create asynchronism. With a traditional BeginInvoke in a new method that I call from the View instead of LoadData it works fine.</p>
  
  <pre><code>public partial class MainPage : PhoneApplicationPage
  {
      [...]
  
      private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
      {
          App.ViewModel.GetData();
      }
  }
  </code></pre>
  
  <p>I use a property that I called CurrentDispatcher, it is filled in the App.xaml.cs with App.Current.RootVisual.Dispatcher.</p>
  
  <pre><code>public class MainViewModel : ViewModelBase
  {
      [...]
  
      public Dispatcher CurrentDispatcher { get; set; }
  
      public void GetData()
      {
          this.CurrentDispatcher.BeginInvoke(new Action(LoadData));
      }
  
      [...]
  }
  </code></pre>
  
  <p>But I would like to use Reactive Extentions. So I tried different elements of Rx like ToAsync or ToObservable for example but I had some "UnauthorizedAccessException was unhandled" with "Invalid cross-thread access" when I add an item to the Checklist.</p>
  
  <p>I tried to ObserveOn other threads cause maybe the error comes from mix between the UI and the background threads but it doesn't work. Maybe I don't use Rx like I would be in that particular case?</p>
  
  <p>Any help would be much appreciate.</p>
  
  <p>EDIT after your answers:</p>
  
  <p>Here is a code which works great!</p>
  
  <pre><code>public void GetData()
  {
      Observable.Start(() =&gt; LoadData())
      .ObserveOnDispatcher()
      .Subscribe(list =&gt;
      {
          foreach (Item it in list)
          {
              this.Checklist.Add(it);
          }
      });
  }
  
  public ObservableCollection&lt;Item&gt; LoadData()
  {
      var results = new ObservableCollection&lt;Item&gt;();
  
      using (ItemDataContext context = new ItemDataContext(_connectionString))
      {
          //Loading
  
          var contextItems = from i in context.Items
                             select i;
  
          foreach (Item it in contextItems)
          {
              results.Add(it);
          }
      }
  
      return results;
  }
  </code></pre>
  
  <p>As you see I didn't use correctly before. Now I can use a ObservableCollection and use it in the Susbscribe. It's perfect! Thanks a lot!</p>