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

Virtual weirdness

3 Answers 99 Views
Data Virtualization
This is a migrated thread and some comments may be shown as answers.
Gunnar
Top achievements
Rank 1
Gunnar asked on 15 Mar 2011, 05:26 PM

I'm using the recommended configuration for virtual loading:

var context = new myContext();
var query = context.GetmyQuery().OrderBy(o => o.ID);
query.IncludeTotalCount = true;
var view = new VirtualQueryableCollectionView() { LoadSize = 10, VirtualItemCount = 100 };
view.ItemsLoading += (s, e) =>
{
    context.Load<myData>(query.Skip(e.StartIndex).Take(e.ItemCount)).Completed += (sender, args) =>
    {
        var lo = (LoadOperation)sender;
        if (lo.TotalEntityCount != -1 && lo.TotalEntityCount != view.VirtualItemCount)
        {
            view.VirtualItemCount = lo.TotalEntityCount;
        }
        view.Load(e.StartIndex, lo.Entities);
    };
};
DataContext = view;

Using the SQL profiler I see some mysterious behaviour:
  1. A call to SQL is made to get the total count of objects
  2. A call to SQL is made to retrieve the 10 first objects.
  3. Nothing happens for 3 seconds (not on screen and not in the SQL contact)
  4. A call to SQL is made to get the total count of objects.
  5. A call to SQL is made to get the 10 first(!) objects.
  6. The Grid is updated on screen.
  7. A call to SQL is made to get the total count of objects
  8. A call to SQL is made to get objects 11-20
  9. A call to SQL is made to get the total count of objects.
  10. A call to SQL is made to get objets 11-20
  11. ...and so on...

This rases three questions (at least...)

  1. Why is everything paused in 3 seconds after the initial SQL query?
  2. Why is every batch of 10 objects read twice from SQL ?
  3. Why is the total count of objects queried before every 10-object batch read?

(Using Q3 2010 SP1, EF4)

3 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 18 Mar 2011, 10:32 AM
Hi,

 Here is an example how to fix this:

var shouldLoad = true;
var context = new myContext();
var query = context.GetmyQuery().OrderBy(o => o.ID);
query.IncludeTotalCount = true;
var view = new VirtualQueryableCollectionView() { LoadSize = 10, VirtualItemCount = 100 };
view.ItemsLoading += (s, e) =>
{
    if (!shouldLoad)
    {
       shouldLoad = true;
       return;
    }
    context.Load<myData>(query.Skip(e.StartIndex).Take(e.ItemCount)).Completed += (sender, args) =>
    {
        var lo = (LoadOperation)sender;
        if (lo.TotalEntityCount != -1 && lo.TotalEntityCount != view.VirtualItemCount)
        {
            shouldLoad = false;
            view.VirtualItemCount = lo.TotalEntityCount;
        }
        view.Load(e.StartIndex, lo.Entities);
    };
};
DataContext = view;


I'm not sure however what can cause the 3 seconds delay. 


Regards,
Vlad
the Telerik team
0
Gunnar
Top achievements
Rank 1
answered on 18 Mar 2011, 09:13 PM
Thanks, that made things a little bit better.There is still an "extra" query for the count in between every batch, but every batch is only requested one time :-) So that was an improvement. (Initially, I regarded the "extra" count query as very unnecessary, but I realize now that it might be required in a live environment since the count might change during paging..)

The delays are still there. I've tried to run my app, Visual Studio and the SQL Profiler side-by-side to figure out what is going on. It's a bit hard to have eyes on three windows at the same time, but as far as I can tell, the sequence is as follows:

  • I click the button to initiate the query.
  • The code you defined is immediately executed up to the point context.Load
  • Nothing happens for 3 seconds. I have a breakpoint at the server side, and this breakpoint isn't hit until 3 seconds after the context.load() call. (client and server run on the same box, so there's no network latency involved)
  • When the first 10 items are returned, the GridView is immediately formatted on screen (headers, column widths, and so on), but no data is displayed.
  • Another 3 second delay where nothing happens.
  • The first 10 items are displayed on screen and at the same time the server service is hit to get the next 10 items.
  • From that point on, everything goes at top speed with just milliseconds in delays between received items, display and the next service call.
0
SPE
Top achievements
Rank 1
answered on 01 Jun 2011, 01:01 AM
setting the RadGridView's ScrollMode to 'Deferred' will prevent the ItemsLoading event being called twice.
however, it will still be called twice for the topmost items when the RadGridView is initially loaded. but for the rest of the items it will not be called twice. hope this helps.
Tags
Data Virtualization
Asked by
Gunnar
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Gunnar
Top achievements
Rank 1
SPE
Top achievements
Rank 1
Share this question
or