Skip to main content

Microsoft Silverlight

Answered Question Embeded aysnc call prolemRSS Feed

(0)

kent.zhou
kent.zhou

Member

Member

109 points

397 Posts

Embeded aysnc call prolem

I tried to create a 3 levels tree. Each level is loaded data from different database table use ADO.NET Data service with aysnc call.

Problem is: if the data amount is small, say total records under 100 or 200. it works fine. But if the data amount is bigger, say it over 1000 rows. everytime When I load the treeview in testing page, I get different results! Everytime when load the control, it will miss some different nodes. It's crazy.  How to slove this issue?

Sample code is here. xmal following the partern from sample form toolkit sample for toolkit: NestedHierarchicalDataTemplateSample.xaml

(First level: BatchType, second Level: Batch, third Level: BatchProduction)


namespace Myspace
{
    public partial class DataTree : UserControl
    {
        public DataTree()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(TreeBatches_Loaded);
        }

        //loaded from proxy directly       
        void TreeBatches_Loaded(object sender, RoutedEventArgs e)
        {
            RRMLookups svcContext = new RRMLookups(new Uri("LookupService.svc", UriKind.Relative));
            DataServiceQuery<ctBatchType> query = svcContext.ctBatchTypes;

            //first async call
            query.BeginExecute(delegate(IAsyncResult ar)
            {
                Collection<BatchTypeNode> allTypes = new Collection<BatchTypeNode>();
                IEnumerable<ctBatchType> results = query.EndExecute(ar).ToList();
                foreach (ctBatchType bt in results)
                {
                    BatchTypeNode node = new BatchTypeNode(bt.BatchTypeID, bt.BatchTypeName);
                    //if needed to load sub batches
                    try
                    {
                        RRMEntities svcx = new RRMEntities(new Uri("DataService.svc", UriKind.Relative));
                        //use linq to get all batches for the specific batchtypeid                                       
                        DataServiceQuery<Batch> subquery =
                            (DataServiceQuery<Batch>)
                            (from b in svcx.Batches
                             where (b.BatchTypeID == node.BatchTypeID) && (b.BatchStatusID == 1)
                             select b);

                        //second async call
                        subquery.BeginExecute(delegate(IAsyncResult aResult)
                        {
                            var y = subquery.EndExecute(aResult).ToList();                           
                            foreach (Batch batch in y)
                            {
                                BatchNode batchNode = new BatchNode(batch.BatchID, batch.BatchName);
                              
                                    DataServiceQuery<BatchProduction> subqueryr =
                                    (DataServiceQuery<BatchProduction>)
                                        (from p in svcx.BatchProductions
                                         where (p.BatchProduction.BatchID == batchNode.BatchID)
                                         select p);

                                    //third async call
                                    subqueryr.BeginExecute(delegate(IAsyncResult zResult)
                                    {
                                        var z = subqueryr.EndExecute(zResult).ToList();
                                        if (z != null)
                                        {
                                            foreach (BatchProduction bp in z)
                                            {
                                                HeaderNode hNode = new HeaderNode(bp.BatchHeaderID, bp.ProductionNameEDI);
                                                batchNode.Headers.Add(hNode);
                                            }
                                        }
                                        batchNode.IsLoaded = true;                                     

                                        if (isAsyncDone(allTypes))
                                        {
                                            BatchTree.ItemsSource = allTypes as IEnumerable<BatchTypeNode>;
                                        }
                                    }, null);
                                                             
                                node.Batches.Add(batchNode);
                            }
                            node.IsLoaded = true;                           
                        }, null);

                    }
                    catch (DataServiceRequestException ex)
                    {
                        //log the error
                        Debug.WriteLine(string.Format("OnGetBatchDataSync Error {0}"), ex.Response.ToString());
                    }

                    allTypes.Add(node);
                }               
            }, null);
        }

        private bool isAsyncDone(Collection<BatchTypeNode> allTypes)
        {
            bool isDone = true;
            foreach (BatchTypeNode node in allTypes)
            {
                isDone = isDone && node.IsLoaded;              
            }
            return isDone;
        }
     }
}

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP

Re: Embeded aysnc call prolem

First off, don't use all those anonymous delegates. It makes your code very difficult to read and follow. When you make that many async calls at once they will get queued up by the browser. The order they get executed in is not guaranteed, so this is why you're getting such mixed results.

I would suggest you load the first level, then loop through that to load the second level and so on. Otherwise you will not get the results in order.

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.

kent.zhou
kent.zhou

Member

Member

109 points

397 Posts

Re: Embeded aysnc call prolem

 As you said, I tried load first level, then loop the nodes at first level and load the second level and so on. Problem here is every time when tried to get data from database, the only way is async call. there is no way to load all data with on async call.

bryant
bryant

Star

Star

9937 points

1,629 Posts

Silverlight MVP
Answered Question

Re: Embeded aysnc call prolem

What if you just load the first level and then only load the other levels on demand? Are the levels all shown at once or are some of them hidden?

If you control the server side you could return the results as a single result instead of making multiple calls...

-- bryant

Blog | Twitter
_________________
Dont forget to click "Mark as Answer" on the post that helped you.
  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities