Virtual weirdness

4 posts, 0 answers
  1. Gunnar
    Gunnar avatar
    28 posts
    Member since:
    Aug 2009

    Posted 15 Mar 2011 Link to this post

    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)

  2. Vlad
    Admin
    Vlad avatar
    11100 posts

    Posted 18 Mar 2011 Link to this post

    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
  3. DevCraft banner
  4. Gunnar
    Gunnar avatar
    28 posts
    Member since:
    Aug 2009

    Posted 18 Mar 2011 Link to this post

    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.
  5. SPE
    SPE avatar
    34 posts
    Member since:
    Sep 2010

    Posted 31 May 2011 Link to this post

    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.
Back to Top