Skip to main content
Home Forums Silverlight Programming WCF RIA Services question on one UI for mutiple async call to load data from ria service
7 replies. Latest Post by Casimodo72 on November 4, 2009.
(0)
kent.zhou
Member
110 points
403 Posts
11-02-2009 3:24 PM |
When using rial service loading data for UI elements, all calling are async call. So if on single UI screen, feeding data from viewmodel, then each async call only give you one dataset(normally, you can't use one async call to get all data even using eager-loading with for association, for example, maybe many lookup for dropdown/combox), so for this case, how can I know all data loaded for the screen? need to check all async call to see if they are completed?
If I use activity control for async call, that means each async call for each UI element need a activity control, may be this is not good for user experience also not good for code maintaince.
Solution or best practice for this problem?
prujohn
Contributor
3579 points
704 Posts
11-02-2009 3:38 PM |
If I get you right, you are needing to make multiple async calls to RIA Services in order to complete your UI presentation.
There are two approaches here that I've used, depending on requirements of my UI:
1. Send all async requests at the same time. As the returns are received, use boolean flags to determine when all returns have received. So you would have a boolean for each call, and then as each call returns they would set their respective flag to "true" (or "complete" then call a helper method to check if all flags are set to true. If all flags are true, then you can remove the activity control.
2. Chain async requests together, so as each call is returns, you make the next async call and so on. When the last call returns, then you can remove the activity control.
I'm sure there are some other approaches, but those are the two that I've used the most.
11-02-2009 3:50 PM |
thank you. One more question: How can you send all async call at same time?One line code for all call or multiple calls? like:
CallAllAsyncCall(...)......;
Or
AsycCallA(....)... ;
AsycCallB(....)... ;
AsycCallC(....)... ;
...
Sample code please.
11-02-2009 5:19 PM |
For RIA Services, the pattern would be:
var result1 = myRIAContext.Load(myRIAContext.Query1());
var result2 = myRIAContext.Load(myRIAContext.Query2());
var result3 = myRIAContext.Load(myRIAContext.Query3());
result1.Completed += (sender1, args1) => {
//process results...
var so = (LoadOperation)sender1;
if (so.HasError){
//... inspect so.Error
}else{
//results in so.Entities
}
};
result2.Completed += (sender2, args2) => {
//process results here
result3.Completed += (sender3, args3) => {
Casimodo72
301 points
159 Posts
11-02-2009 7:29 PM |
I had the same issue. A big activity spanning the whole page and multiple nested activities doing some detail work. Looked like a primeval forest of progressbars.Some ideas:1) Normally Colin Blair does not recommend subscribing to the Completed event of the resulting LoadOperation when doing Load(...), because that load operation won't be garbage collected since it has a reference to your ViewModel (use the callback in the Load(...) method). Although, I dunno what overhead a dangling LoadOperation produces - maybe negligible. Maybe there might also be an issue when mocking (e.g. for tests) the DomainClient, such that it returns too early; i.e. when your subscription occurs after the Completed event was fired.2) If you're going MVVM then you are actually free to invent a DDS like thingy which encapsulates the load for you and could do the following: a) Call the Load(...) and provide a callback. b) When the callback is called the DDS like thingy could automatically pop up an error report view when something went wrong. c) The DDS like thingy would have a IsLoading property and a LoadingCompleted event, so that you could nicely do the following in your ViewModel: c.1) OnMyDDSLikeThingiesLoadingCompleted() { this.IsBusy = MyDDSA.IsLoading || MyDDSB.IsLoading || MyDDSC.IsLoading. }3) If your loading needs to be sequential, then you could also implement in your DDS like thingies a convenient way of defining a state machine which triggers your loads in the desired order.I wouldn't recommend coding the logic for compositional load operations again and again in your ViewModels, but anchoring such functionality in your DDS like thingy and expose a nice and convenient API.
[edited]The DDS like thingy is actually something like the SuperEmployeesViewModel described in Brad Abrams blog:http://blogs.msdn.com/brada/archive/2009/09/07/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-viewmodel.aspxAlthough it could be much more generic, powerfull and convenient.It's based on stuff of Nikhil Kothari and Jeff Handley.I wish they would have thought this over before exposing the evil DDS (and all its underlying machinery).[/edited]Regards,Kasimier
11-02-2009 7:48 PM |
Regarding the Activity Control: does a nice control template already exist? Something non-linear and rather bloomy?
ColinBlair
6741 points
1,318 Posts
11-03-2009 2:44 PM |
Casimodo72:1) Normally Colin Blair does not recommend subscribing to the Completed event of the resulting LoadOperation when doing Load(...), because that load operation won't be garbage collected since it has a reference to your ViewModel (use the callback in the Load(...) method). Although, I dunno what overhead a dangling LoadOperation produces - maybe negligible.
It depends on how many records you loaded and if you ever referenced the LoadOperation's Entities property. If you referenced the lo.Entities property then the LoadOperation is also holding a reference to every entity that was loaded by the LoadOperation. That sounds like a pretty massive memory leak to me.
11-04-2009 6:40 AM |
ColinBlair: If you referenced the lo.Entities property then the LoadOperation is also holding a reference to every entity that was loaded by the LoadOperation. That sounds like a pretty massive memory leak to me.
Ah, right.
Regards & thanks,
Kasimier