Initially I broke each request into 2 methods:
- The call to the service to retrieve the data.
- The async callback method to process the data.
Now coming from a VB.NET background this was just the way you had to do things, and you became very familiar with the AddressOf operator very quickly. Along comes C#.NET and the idea of anonymous methods to solve the problem. Most of the methods we them modified to use Anonymous Methods. This allowed all code for a single process to be encapsulated into a single method, significantly reducing the number of tightly coupled methods, greatly increasing readability and maintainability.
The following is an example of some Silverlight code before and after the change. As you can see the amount of code written has been reduced, it is more readable and maintainabled, you do not have to perform some validation as you can be certain of the data being passed in and finnally you have access to the variables within the calling method. Beware though of accessing variables within the main method as they may provide a warning of "Access to modified closure", I won't describe what that is now, too far off topic.
Before Anonymous Methods
/// <summary> /// Populate the the configuration entity /// </summary> private void PopulateConfigData() { DataServiceQuery query = (DataServiceQuery<configuration>)from config in _Service.configurationSet select config; query.BeginExecute(new AsyncCallback(PopulateConfigData_CallBak), query); } /// <summary> /// Builds the config entity /// </summary> /// <param name="ar">Results of Async operation</param> private void PopulateConfigData_CallBak(IAsyncResult ar) { DataServiceQuery query = ar.AsyncState as DataServiceQuery; if (query == null) { throw new DataServiceQueryException("No configuration data returned."); } // load configuration information DataServiceCollection<configuration> results = new DataServiceCollection<configuration>(query.EndExecute(ar) as IEnumerable<configuration>); if (results.Count > 0) { _Config = results[0]; } else { throw new DataServiceQueryException("No configuration data returned."); } // continue processing requests ContinueProcessing(); }
After Anonymous Methods
/// <summary> /// Populate the the configuration entity /// </summary> private void PopulateConfigData() { DataServiceQuery query = (DataServiceQuery<configuration>)from config in _Service.configurationSet select config; query.BeginExecute(result => { // load configuration information DataServiceCollection<configuration> results = new DataServiceCollection<configuration>(query.EndExecute(result) as IEnumerable<configuration>); if (results.Count > 0) { _Config = results[0]; } else { throw new DataServiceQueryException("No configuration data returned."); } // continue processing requests ContinueProcessing(); }, null); }