Skip to main content
Home Forums Silverlight Programming Silverlight Controls and Silverlight Toolkit Embeded aysnc call prolem
3 replies. Latest Post by bryant on December 18, 2008.
(0)
kent.zhou
Member
109 points
397 Posts
12-17-2008 8:24 PM |
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
Star
9937 points
1,629 Posts
12-17-2008 11:17 PM |
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.
12-18-2008 9:29 AM |
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.
12-18-2008 10:33 AM |
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...