This is a migrated thread and some comments may be shown as answers.

Main Thread Blocked When Loading IEnumerable

12 Answers 219 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Rodney Foley
Top achievements
Rank 1
Rodney Foley asked on 08 Nov 2010, 11:34 PM
Greetings,

I have a RadGridView that is bound to a DomainDataSource for a WCF RIA Serivce. This returns an IEnumerable<T>.  This is inside a model RadWindow and the RadGridView is contained within a RadBusyIndicator that is bound the the DomainContext.IsLoading.  

The busy indicator comes up and is animated and then when the data is retrieved it freezes along with the whole silverlight application. This appears to be happening while the IEnumerable is being iterated by the RadGridView.  

Minor Digression: I have set my MaxHeight to 1200, but I have left the Height at default so that it can stretch to fit the window.  So please don't bring up the bug about infinity height's on a RadGridView as that doesn't appear to be the issue here. It acts the same with 1200 or infinity. Please fix this bug, I complained about this to support directly over a year ago, and 3 major releases later this issue is still in the product. Anyway...

Below is the layout root for the RadWindow in question.  I hope
<Grid x:Name="LayoutRoot"
        Margin="2">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
 
    <riaControls:DomainDataSource Name="dataSource"
                                    QueryName="GetAllOpenArchitectureWorkItemsForDateQuery"
                                    AutoLoad="False">
        <riaControls:DomainDataSource.DomainContext>
            <web:TfsDomainContext/>
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.QueryParameters>
            <riaControls:Parameter ParameterName="date"/>
        </riaControls:DomainDataSource.QueryParameters>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="Id"
                                        Direction="Ascending"/>
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
    <StackPanel Orientation="Horizontal"
                Grid.Row="0"
                Grid.Column="0">
        <TextBlock Text="Count: "
                    Margin="4"
                    VerticalAlignment="Center"/>
        <TextBlock Name="countText"
                    Margin="4"
                    VerticalAlignment="Center"
                    Text="{Binding ElementName=dataSource, Path=DomainContext.WorkItemDatas.Count}"/>           
    </StackPanel>
    <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Right"
                Grid.Row="0"
                Grid.Column="0">
        <TextBlock Text="Export: "
                    Margin="0"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Right"/>           
        <telerik:RadButton Name="exportToExcel"
                            Margin="4"
                            Click="exportToExcel_Click">
            <ToolTipService.ToolTip>
                <ToolTip Content="Export to Excel"/>
            </ToolTipService.ToolTip>
            <Image Height="16"
                    Margin="1"
                    Source="excel_16x16.png"/>
        </telerik:RadButton>
        <telerik:RadButton Name="exportToHtml"
                            Margin="4"
                            Click="exportToHtml_Click">
            <ToolTipService.ToolTip>
                <ToolTip Content="Export to Html"/>
            </ToolTipService.ToolTip>
            <Image Height="16"
                    Margin="1"
                    Source="html_16x16.png"/>
        </telerik:RadButton>
    </StackPanel>
 
    <ScrollViewer
        Grid.Row="1"
        Grid.Column="0"
        HorizontalScrollBarVisibility="Auto"
        IsEnabled="True"
        Visibility="Visible"
        VerticalScrollBarVisibility="Auto"
        BorderThickness="0">
        <telerik:RadBusyIndicator
            Height="Auto"
            Name="busyIndicator"
            Width="Auto"
            BusyContent="Loading Work Items..."
            IsBusy="{Binding ElementName=dataSource, Path=DomainContext.IsLoading}">
            <telerik:RadGridView
                Name="detailGridView"                    
                Margin="-2"
                AutoGenerateColumns="True"
                IsReadOnly="True"
                Height="Auto"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                Width="Auto"
                ShowGroupPanel="False"
                SelectionMode="Multiple"
                ItemsSource="{Binding Data, ElementName=dataSource}"
                MaxHeight="1200">
            </telerik:RadGridView>
 
        </telerik:RadBusyIndicator >   
 
    </ScrollViewer>      
         
    <telerik:RadButton x:Name="OKButton"
                        Content="OK"
                        Click="OKButton_Click"
                        Width="75"
                        Height="23"
                        HorizontalAlignment="Right"
                        Margin="4"
                        Grid.Row="3"
                        Grid.Column="0"/>
</Grid>

12 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 09 Nov 2010, 08:30 AM
Hello,

Do you get different behavior with standard Silverlight DataGrid in this case?

Kind regards,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 09 Nov 2010, 04:59 PM
Hi Vlad,

Really? You are going to go there?  Try to either blame it on the toolkit, or to say "hey we are the same".  As if either of those are acceptable.

For the record I was using the toolkit DataGrid before switching to the RadGridView, and it worked much better in the area of performance. It had a minor main thread blocking for a brief moment and then recovered and was good.  However, the RadGridView is exponentially worse it is unbelievable. After doing some more testing and using it bound to a Ria Service returned IEnumerable<T> I have more Main Thread blocking and performance issues to report.

  1. There is on the data loading that is controlled internally by the RadGridView since I am using declarative binding.  It blocks the main thread once it gets the IEnumerable<T> from the service. This collection has never had more than 180 items in and even on the ones with 20 items it is noticeable.
  2. When grouping on a single column on a RadGridView with less than 180 items it takes a a tad longer than expected to finish the grouping, but it doesn't appear to block the main thread which is good at least.
  3. When removing the single group  in #2 it is much worse as not only does it block the main thread it does it for a very long time, it takes just as long to ungroup if not longer than it took to load the data.  It feels like it is requesting the data again from the service which would be wrong since it should already have the data since it just grouped it.
  4. When I set DataLoadMode to Asynchronous it gets "wonky" the RadBusyIndicator stops working on the data load and all I get is a black grid area until the data loads, and the data looks off and doesn't have all the records.  There are empty rows that have no column lines and just a ">" symbol in the row header. So this doesn't seem to do what it sounds like it should.
  5. However, when in Synchronous mode the RadBusyIndicator only shows when the window is opened the first time, ever other time the window is shown it doesn't show the indicator.  This happened when I switched from the toolkit ChildWindow, the toolkit BusyIndicator, and the toolkit DataGrid.  With the toolkit everything worked great, switching over to Rad components made act strange. Nothing really changed, since the two indicators and the properties I where using matched, and the only change for the RadWindow was to call close when my Ok button was clicked, that wasn't needed in the ChildWindow, and then to call ShowDialog instead of Show.  The grids matched up well since I was letting it auto gen the columns.  I did change the selection mode on the GridView since you have a 3rd nice option Multiple, and I had to set the MaxHeight to be safe.  One or more of you components do not like to work as expected when setting them up like the toolkit counterparts when it comes to Busy Indicators.  I wrap this under perceived performance issue as the busy indicator is what notifies user about long waits and shows that things are progressing.

To me you are violating the rule related to not doing things that take to much time on the main GUI thread.  In WinForms and ASP.net the developer is expect to be responsible for this when using the components.  However now with XAML and trying to do things declaratively the components should become more aware and do threading internally to keep data loading from blocking.  Because of how you guys are doing this even if I do everything programmatically and managing the threading myself there will still be the delay and main thread blocking when I have to set the IEnumerable<T> to the ItemsSource property.

As I understand it you have a RadObservableCollection<T> that you want people to use for data being set to your components as I have read in other forum posts this would help solve some if not all of the performance issues.  However since I cannot return a RadObservableCollection<T> from a Ria Service I cannot declaratively bind to a RadObservableCollection<T> that I am aware of and I can't find any examples in your Silverlight help doc's.  So I would have to do this all programmatically and either use the constructor to pass it the IEnumerable<T> or transform it in some other method to a RadObservableCollection<T>.  

All the solutions require me the development user of your components to do a lot of extra overhead and takes me away from the beauty declarative XAML and into the code behind.  
0
Vlad
Telerik team
answered on 09 Nov 2010, 05:06 PM
Hi,

 You get such performance problem since the grid is measured with infinity in your case. When a UI virtual component (like RadGridView, DataGrid, ListBox, etc.) is measured with infinity the component will try to create all rows + all cells at once.

Regards,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 09 Nov 2010, 05:35 PM
Hi Vlad,

So lets get one of you to be very specific on WHAT CANNOT BE SET TO INFINITY.  I have never once seen any of you be specific, just general, and it is no where in your API docs.

So as you can see I have set my MaxHeight to 1200 in the code I posted. I got this from a form post you where part of that said this worked.  It doesn't work for me.  So there are 5 properties on a RadGridView that have the word Height in them, which one is responsible for the performance is?  Am I to assume it is the main Height property as that is the only one still set to Auto for me?

Can I have MaxHeight set to infinity or does this need to be set as well?  So does this could for Width as well since yo mentioned CELLS? do I have to have my Width set to something since the number of columns could be large and impacting the number of cells it is trying to make?

Please, please be very specific in how to fix all my performance whoas with your components that I specified?  

Because as soon as I set the Height and Width I am screwed as it will stop resizing beyond the the size set.  If I set MinHeight to 0, MaxHeight to 1200 and Height to 100, all I get is the 100.  If Height is set to Auto then it will grow between 0 and 1200. So if you are saying I have to loose a feature to gain performance with your controls please be specific, as I do not have this issue with the toolkit controls for Silverlight 4.

Update
I tried this by setting height to 100, and it became very fast but unusable. I set it to 1200 to match the Max and it has the same issues. So while I think you are correct in this impacting the performance it doesn't seem to work very well when you want a RadGridView that can be resized to the users wishes (like excel), some of our users like to MaxImize the window so the grid will fill the screen.  

How can I allow this and still get the performance of a setting like 100?
Why don't you guys try to fix this in your controls and be smarter about how you create your cells when its on any size, especially Auto? Why not just look at the size it will be or is displayed at and just use that?
0
Accepted
Vlad
Telerik team
answered on 09 Nov 2010, 05:43 PM
Hello,

 In my opinion you should not nest RadGridView inside ScrollViewer since the grid (not measured with infinity height) will provide scrollbars by default + you can minimize the XAML even more (remove the busy indicator) if you bind the IsBusy property to your to DomainDataSource similar to our demo. Keep in mind that UI components associated with Grid.Row with Height set to Auto will be measured with infinity height as well. 

All the best,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 09 Nov 2010, 05:55 PM
Okay you are still not be specific enough. I asked how to I make my RadGridView size to the window size (and there no paging) and you basically said don't use a ScrollViewer because you have a built in one, don't you your busy indicator because you have a built in one, and then don't use a Grid "Auto" or "*" or just don't use a Grid but it is the one that lets the component GROW to fit an area.

Issues:
  1. Your demo has a RadDataPager which changes a lot of things, and that I do not want to use. Using one allows you to fix the height of your grid since you know how many rows will be shown at once. This doesn't solve my problem with allowing all the rows displayed and allowing the user to maximize the window to see more.  
  2. Your built in busy indicator doesn't show text, just the animation, how do you add the text and the "window" looking box?

You guys claim to have very fast performing RadGridView with millions of records without paging but you can't handle less that 200 rows when I try to do some rather simple use cases with your RadGridView. 
0
Vlad
Telerik team
answered on 09 Nov 2010, 06:01 PM
Hi,

 You don't have to do anything special to size the grid to window. This will be done by default by the Silverlight layout when using Grid. I've attached an example project to illustrate you this. If you want to modify the grid loading indicator you can use Blend (modify directly the grid templates). 

All the best,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 09 Nov 2010, 06:18 PM
Your sample is not realistic. You have a RadGridView in a Grid by itself without rows or column definitions, you are binding it to an ObservableCollection<MyObject> which has 100,000 rows with two columns which is done in code behind. It is not a real world binding and it is not real world use of a grid.

So you know I have made the following changes to remove the ScrollViewer and the RadBusyIndicator but I have forced the Auto on the grid for emphasis left the grid row and column definitions with the "*".  Already the performance on all accounts has improved while leaving the infinity issue unchanged.  It works as I expect it to still, grouping and ungrouping are instantaneous, there is no main thread blocking anymore, the busy indicator is working on future reloads, and anytime the data source is busy.  So I am very happy with these changes, and it is all working without making any changes you actually said impact performance.  

It seems the height issue is either not an issue with Silverlight 4 and .Net 4 or it has always been a fallacy.  It seems I was doing something wrong, but nothing that I would expect someone coming from the Silverlight Toolkit to not to do.  I think that combetting scrollviewers may have screwed up something, and the RadGridView doesn't like being inside a RadBusyIndicator. However one or the combo of both killed the performance not the Height set to infinity. 

So thank you Vlad for your suggestions about those two other issues as they actually where the read issue with performance.  You really should document this somewhere and you should stop pointing the finger at the Height and Infinity as that has no impact on my issues.

<Grid x:Name="LayoutRoot"
        Margin="2">
         
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
         
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
 
    <riaControls:DomainDataSource Name="dataSource"
                                    QueryName="GetAllOpenArchitectureWorkItemsForDate"
                                    AutoLoad="False">
        <riaControls:DomainDataSource.DomainContext>
            <web:TfsDomainContext/>
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.QueryParameters>
            <riaControls:Parameter ParameterName="date"/>
        </riaControls:DomainDataSource.QueryParameters>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="Id"
                                        Direction="Ascending"/>
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
         
    <StackPanel Orientation="Horizontal"
                Grid.Row="0"
                Grid.Column="0">
             
        <TextBlock Text="Count: "
                    Margin="4"
                    VerticalAlignment="Center"/>
             
        <TextBlock Name="countText"
                    Margin="4"
                    VerticalAlignment="Center"
                    Text="{Binding ElementName=dataSource, Path=DomainContext.WorkItemDatas.Count}"/>  
             
    </StackPanel>
         
    <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Right"
                Grid.Row="0"
                Grid.Column="1">
             
        <TextBlock Text="Export: "
                    Margin="0"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Right"/>   
             
        <telerik:RadButton Name="exportToExcel"
                            Margin="4"
                            Click="exportToExcel_Click">
            <ToolTipService.ToolTip>
                <ToolTip Content="Export to Excel"/>
            </ToolTipService.ToolTip>
            <Image Height="16"
                    Margin="1"
                    Source="excel_16x16.png"/>
        </telerik:RadButton>
             
        <telerik:RadButton Name="exportToHtml"
                            Margin="4"
                            Click="exportToHtml_Click">
            <ToolTipService.ToolTip>
                <ToolTip Content="Export to Html"/>
            </ToolTipService.ToolTip>
            <Image Height="16"
                    Margin="1"
                    Source="html_16x16.png"/>
        </telerik:RadButton>
             
    </StackPanel>
             
    <telerik:RadGridView
        Grid.Row="1"
        Grid.Column="0"
        Grid.ColumnSpan="2"
        Name="detailGridView"                    
        Margin="-2"
        AutoGenerateColumns="True"
        IsReadOnly="True"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        Height="Auto"
        Width="Auto"
        SelectionMode="Multiple"
        ItemsSource="{Binding Data, ElementName=dataSource}"
        IsBusy="{Binding ElementName=dataSource, Path=DomainContext.IsLoading}"
        CanUserDeleteRows="False"
        CanUserInsertRows="False">
             
    </telerik:RadGridView>
         
    <telerik:RadButton x:Name="OKButton"
                        Content="OK"
                        Click="OKButton_Click"
                        Width="75"
                        Height="23"
                        HorizontalAlignment="Right"
                        Margin="4"
                        Grid.Row="2"
                        Grid.Column="1"/>
</Grid>

0
Vlad
Telerik team
answered on 10 Nov 2010, 07:57 AM
Hello,

 I'm not sure how the grid binding and/or columns definition is related to how the grid will be measured from the parent container. Can you clarify? The idea of my example (made in less than a minute) was to show you how the Grid layout (the default in Silverlight pages and user controls) can help you to achieve your goal and to avoid problems in the future. You may need to check also this help article again to avoid further problems. 

If our examples are not useful for you and you do not believe me that you will get serious performance problems with UI virtual controls (even simple ListBox) when measured with infinity, you can ask the same questions on official Silverlight forums or Stackoverflow.  

Best wishes,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 10 Nov 2010, 05:27 PM
Vlad,

"I'm not sure how the grid binding and/or columns definition is related to how the grid will be measured from the parent container. Can you clarify?" -Vlad

I am not sure why you are asking me this? I was explaining why your example has nothing to do with the issue at hand and is not a real world example.  But to answer you questions they are related because they show you making a grid similar to mind in all aspects and then only making the one or two changes that you claim will fix an issue as proof.  

As I have said I posted my XAML code as to what fixed the issue and it is that your RadGridView doesn't seem to play well with RadBusyIndicator, and possible ScrollViewer. My example of what I am using in a production application shows that performance is not impacted by "AUTO" on the height nor is it impacted by Grid being set to Auto or an asterisk.  

What I am saying is I am calling BS on your companies constant claims that leaving these things set as your link claims doesn't make sense and if they are true they are a friggin' bug.  If having default settings and using things that making the user experience better like having a control even a grid fit to the size of the space is wrong and that this goes to the core controls from Microsoft then WPF and Silverlight  are crap.  

However they are not crap and never once have I had a performance issue with the core components that changing the settings to fix my height or not allowing the Grid to child to grow to fit the available space.  

In short you your claims about infinity are a Red Herring since I have since no proof, and I have proof to the contrary that the performance issues I was experiencing where related to RadGridView not playing nice with others that the Toolkit DataGrid seems to do just fine.
0
Vlad
Telerik team
answered on 11 Nov 2010, 08:32 AM
Hello,

 You can check the attached example application which will demonstrate what you will get if you put a standard Silverlight DataGrid with just 2 columns bound to just 10000 records in ScrollViewer.

Greetings,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Rodney Foley
Top achievements
Rank 1
answered on 11 Nov 2010, 05:43 PM
Vlad please drop this you are going off track.  I have very fast performance with infinity using your controls you should be happy and instead you continue trying to prove that I am either lying or that your controls have a bug related to infinity.  Please you are only making this worse the thread should be closed. A while back I marked the post that helped me get to the resolution as answered and I posted what fixed the issue.  This thread is closed, thank you.
Tags
GridView
Asked by
Rodney Foley
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Rodney Foley
Top achievements
Rank 1
Share this question
or