Welcome to the Xceed Community | Help
Community Search  
More Search Options

Cross thread exception when running multiple Dispatcher threads in one UI

Sort Posts: Previous Next
  •  11-02-2010, 3:28 PM Post no. 29098

    Cross thread exception when running multiple Dispatcher threads in one UI

    Hi there, sorry for the length of this post, this is a particularly tricky problem to explain

    I've been evaluating the Xceed grid and have been very impressed to date, but I fear I may have uncovered a bug. 

    To set the scenario, I have an application that uses a control app to spawn multiple windows, each with a dedicated UI thread.  In each of these windows I have a grid which displays large volumes of data, with column definitions configurable by the user.  When I start up the first window all is well, the grid is bound and the data displays and updates as appropriate.  When I start up the second window I get a cross thread exception when trying to set the ItemsSource of the DataGridControl to the View property of my DataGridCollectionViewSource.

    The grid is hosted in a UserControl, which is then hosted in the main Window.  The grid specific xaml is:

    <xcdg:DataGridControl   x:Name="_mainGrid"

                                    ReadOnly="True"

                                    ItemScrollingBehavior="Immediate"

                                    NavigationBehavior="RowOnly" >

                <xcdg:DataGridControl.Resources>

                    <Style TargetType="{x:Type Views:TableflowView}">

                        <Setter Property="AllowColumnChooser" Value="False" />

                    </Style>

                </xcdg:DataGridControl.Resources>

                <xcdg:DataGridControl.View>

                    <Views:TableflowView Theme="{DynamicResource defaultTheme}" RowFadeInAnimationDuration="100" ScrollingAnimationDuration="300" UseDefaultHeadersFooters="False" ShowScrollTip="False">

                        <Views:TableflowView.FixedHeaders>

                            <DataTemplate>

                                <xcdg:HierarchicalGroupByControl Views:TableView.CanScrollHorizontally="False" />

                            </DataTemplate>

                            <DataTemplate>

                                <xcdg:ColumnManagerRow />

                            </DataTemplate>

                        </Views:TableflowView.FixedHeaders>

                    </Views:TableflowView>

                </xcdg:DataGridControl.View>

            </xcdg:DataGridControl>

     

    The important part of the data binding code  (with the thread logging in it) is below:

    public void SetDataBinding<T>(ObservableCollection<T> data, IEnumerable<DynamicColumnDefinition> columnDefs)

            {

     

                var viewSource = new DataGridCollectionViewSource();

                _mainGrid.Columns.Clear();       

     

                // set up the columns

                foreach (var columnDef in columnDefs)

                {

                    var columnItem = new DataGridItemProperty(columnDef.PropertyName, columnDef.PropertyName, typeof (object));               

                    viewSource.ItemProperties.Add(columnItem);

     

                    // build the grid column

                    var dataColumn = getColumn(columnDef.Type);

                    dataColumn.Title = columnDef.Header;

                    dataColumn.FieldName = columnDef.Header;

     

                    _mainGrid.Columns.Add(dataColumn);

                }

     

                // general threading info

                Console.WriteLine("Current Dispacher Thread = {0}", Dispatcher.Thread.ManagedThreadId);

                Console.WriteLine("Current Operational Thread = {0}", Thread.CurrentThread.ManagedThreadId);

                Console.WriteLine("CheckAccess State = {0}", Dispatcher.CheckAccess());

     

                // ViewSource threading info

                Console.WriteLine("Current Grid Thread = {0}", viewSource.Dispatcher.Thread.ManagedThreadId);

                Console.WriteLine("Grid CheckAccess State = {0}", viewSource.Dispatcher.CheckAccess());

     

                // grid threading info

                Console.WriteLine("Current Grid Thread = {0}", _mainGrid.Dispatcher.Thread.ManagedThreadId);

                Console.WriteLine("Grid CheckAccess State = {0}", _mainGrid.Dispatcher.CheckAccess());

     

                viewSource.Source = data;

                _mainGrid.ItemsSource = viewSource.View;         // cross-thread exception here            

            }

     

    On the run that crashes the output of the console output reads:

    Current Dispacher Thread = 25

    Current Operational Thread = 25

    CheckAccess State = True

    Current Grid Thread = 25

    Grid CheckAccess State = True

    Current Grid Thread = 25

    Grid CheckAccess State = True

     

    But I still get the dreaded cross thread exception as follows:

     

    System.InvalidOperationException

    The calling thread cannot access this object because a different thread owns it.

    Stack trace:

       at System.Windows.DependencyObject.GetValue(DependencyProperty dp)

       at System.Windows.FrameworkElement.get_IsLoaded()

       at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object& source)

       at System.Windows.FrameworkElement.TryFindResource(Object resourceKey)

       at Xceed.Wpf.DataGrid.DefaultCellEditorSelector.SelectCellEditor(Type dataType)

       at Xceed.Wpf.DataGrid.ItemsSourceHelper.GenerateColumnsFromItemsSourceFields(ColumnCollection columns, IDictionary`2 defaultCellEditors, Dictionary`2 fields, Boolean autoCreateForeignKeyConfigurations)

       at Xceed.Wpf.DataGrid.DataGridControl.GenerateColumnsFromItemsSourceFields()

       at Xceed.Wpf.DataGrid.DataGridControl.ProcessDelayedItemsSourceChanged()

       at Xceed.Wpf.DataGrid.DataGridControl.OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)

       at System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

       at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)

       at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)

       at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)

       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)

       at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)

       at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)

       at Forge2.UI.Controls.DynamicGrid.DynamicGrid.SetDataBinding[T](ObservableCollection`1 data, IEnumerable`1 columnDefs) in C:\Enterprise\DOTNET\Forge2\Forge2.UI\Controls\DynamicGrid\DynamicGrid.xaml.cs:line 115

     

    Given all the thread Id and access checks I do I cannot possibly see how the threads could get crossed in my code.  Either I am setting up the data source incorrectly, or, I fear there is something amiss with the binding management of the DataGridControl.

    Please help, this is a complete show-stopper for this otherwise excellent product.

    Kind regards

    Simon

     

     

  •  11-02-2010, 3:36 PM Post no. 29099 in reply to 29098

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Incidentally, even if I try and leave the ItemsSource setting up to the Dispatcher using:

    Dispatcher.Invoke(new Action<DataGridCollectionViewSource>(v => _mainGrid.ItemsSource = v.View), DispatcherPriority.Send, viewSource);

     

    It still falls over with the same exception.  I doubt this is a Dispatcher problem.

     

  •  11-03-2010, 11:04 AM Post no. 29109 in reply to 29099

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi Simon,

    Can you please send us a sample application to support@xceed.com that reproduces this exception so that we can confirm this potential bug?

     

     


    Regards,

    Alain Jreij,

    Web Developer,

    Xceed Software Inc
  •  01-30-2011, 5:30 PM Post no. 29708 in reply to 29109

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi,

     Was there ever a resolution to this problem?  I'm getting the same error and would really like to know if there's a fix for it.

     

    Cheers

    Anthony 

  •  01-31-2011, 4:36 PM Post no. 29711 in reply to 29708

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi Anthony,

    I was able to track this down in our system. Simon had indeed sent us a test project by email, but it was not properly linked to this forum thread, therefore the update here was forgotten.

    This was fixed in version 3.8 (for .NET 3.5) and version 4.1 (for .NET 4.0), in the service release of November 2010.

    If you are still having the issue while using those versions or a more recent one, please send us a test project to support@xceed.com that reproduces the issue so that we can investigate further. Thank you.

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  01-31-2011, 8:49 PM Post no. 29713 in reply to 29711

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi Diane,

    I've sent a sample application that replicates this error to your support email address.

    I'm not really sure what I'm doing wrong. Any help you can give would be greatly appreciated. 

    Cheers

    Anthony 

  •  01-31-2011, 9:56 PM Post no. 29715 in reply to 29713

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    PS.  I've just realised that I sent the email from my new address and not the one associated with my Vanguard subscription.  I did, however, reference this forum post ID in the email header and text so hopefully you can match up the post with the email.

     

    Cheers

    Anthony 

  •  02-02-2011, 12:06 PM Post no. 29729 in reply to 29715

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi Anthony,

    After investigation, this has been confirmed as a bug on our end. Thank you for bringing it to our attention.

    The problem is that the second thread with the grid will access IsFrozen on a Freezable (a static cell editor) that was created at the load of the first grid in a different thread.

    The developer already has an idea on how to fix this, and so it should be included in the next service release. We will post an update in this forum thread when it is ready for download. Thank you for your patience.

    In the meantime, a possible workaround would be for you to manually define your columns in your printview.xaml and to make the CellEditor of each column point to a static resource of CellEditor that is part of the resources of that same printview. This was not tested, but according to the developer it should work.

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  02-02-2011, 4:04 PM Post no. 29732 in reply to 29729

    Re: Cross thread exception when running multiple Dispatcher threads in one UI

    Hi Diane,

    You are a deadset legend (as us Aussies say).  Your suggested workaround fixed the problem for me on the first try. Please tell your developer that he has definitely made my week Big Smile 

     

    Cheers

    Anthony 

View as RSS news feed in XML
Contact | Site Map | Reviews | Legal Terms of Use | Trademarks | Privacy Statement Copyright 2011 Xceed Software Inc.