locked
Entity Framwork and "The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)) RRS feed

  • Question

  • I have a Windows Store app where I am using Entity Framework to access a SQL database.  I have an ItemsControl that I bind to a child entity of my main entity:

            private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
            {
                String EstID = (string)e.NavigationParameter;
    
                //Estimate Est;
    
                Est = await DispatchDataSource.GetEstimate(EstID);
                ItemsGrid.ItemsSource = Est.EstimateCrates;
    }

    All is well if you modify the crates that are already there.  If you click the add button, the function is:

            private void AddButton_Click(object sender, RoutedEventArgs e)
            {
                EstimateCrate c = new EstimateCrate();
                c.ID = Guid.NewGuid();
                Est.EstimateCrates.Add(c);
                TopAppBar.IsOpen = false;
            }
    

    When you hit the save button, you get the error:

    "The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))"

    The code for the save button is as follows:

            private async void SaveButton_Click(object sender, RoutedEventArgs e)
            {
                ItemsGrid.ItemsSource = null;
                await SaveCrates();
                TopAppBar.IsOpen = false;
                ItemsGrid.ItemsSource = Est.EstimateCrates;
            }
    

    I set ItemsGrid (it is an ItemsControl object) Itemsource to null to release the binding on the Entities.  I save the changes, then attach it back.  This works except when you add a new EstimateCrate.  The point that you get the error is on the OnPropertyChanged for EstimateCrate entity for the ID property.  What is puzzling to me is that I had set the ID property back when I created the new crate.  Seems like it might be creating it again.  In any case, it seems to think that something on the UI thread has OnPropertyChanged still hooked.

    Any help would be greatly appreciated.

    Jim


    Jim Wilcox

    Tuesday, December 3, 2013 10:11 PM

All replies

  • I think you need to use the Dispatcher to run the code that is throwing the error.
    Tuesday, December 3, 2013 11:27 PM
  • I tried this:

            private async void SaveButton_Click(object sender, RoutedEventArgs e)
            {
                ItemsGrid.ItemsSource = null;
                await ((MPS_Mobile_Estimator.App)App.Current).Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        DispatchDataSource.SaveEstimate(Est);
                    });
                TopAppBar.IsOpen = false;
                ItemsGrid.ItemsSource = Est.EstimateCrates;
            }
    
    

    I went ahead and directly called the Entity Update function to simplify it.  The update function is as follows:

            public async static Task SaveEstimate(Estimate Est)
            {
                try
                {
                    context.UpdateObject(Est);
    
                    await context.SaveChangesAsync();
                }
                catch (Exception ex)
                {
                    MetroEventSource.Log.Error(ex.ToString());
                }
            }
    

    It is pretty straight forward.  You would think it would be a pretty normal thing to bind an entity collection to an ItemsControl then update it when you are done.  It actually does work great until you add a record, then when you save you get the error.  I wonder if there is a better procedure to add a child object to the collection?


    Jim Wilcox

    Wednesday, December 4, 2013 1:37 AM