7/8/12

Asynchronous programming in .NET - Part 1

Asynchronous programming in .NET is facilitated via Delegates. A delegate is a mechanism that is used to delegate a method call as shown in the code below.



//my custom class in the class library where i have defined the delegate
public class MyCustomDelegates
{
 public delegate string MyFootballDelegate(string team);
}

public class Client
{
 public void ProcessDelegates()
 {
   MyFootballDelegate objDelegate = Dallas;
   objDelegate("cowboys");
 }
 
 private string Dallas(string team)
 {
  //do something here
  return string.format("{0} - {1}","Dallas", team);
 }
}


In the code above, the Client creates an instance of the Delegate called MyFootballDelegate and assigns a method Dallas to it. The Client then invokes the delegate passing in an input value called "cowboys".So what the client is doing is delegating the act of calling that method Dallas to an instance of the MyFootballDelegate class(the compiler internally converts a delegate declaration into a class).

BeginInvoke() and EndInvoke()

In the code above the Client blocks until the method Dallas completes, so this use of delegates is not really asynchronous. To make the call asynchronous the Client needs to invoke BeginInvoke and EndInvoke methods on the delegate as follows:


public class Client
{
 public void ProcessDelegates()
 {
   MyFootballDelegate objDelegate = Dallas;
   iAsyncResult objAsyncresult = objDelegate.BeginInvoke("cowboys",null,null);
   string result = objDelegate.EndInvoke(objAsyncresult);
 }
 
 private string Dallas(string team)
 {
    //do something here
           return string.format("{0} - {1}","Dallas", team);
 }
}


The call to BeginInvoke uses a thread from the .NET Thread pool and queues up the delegate call. So it blocks the calling code for only a brief moment.The Client then calls the EndInvoke to get the result from the method call.

Completion Callback Methods

The Client, instead of calling EndInvoke explicitly, can pass a callback method to the BeginInvoke method that is invoked as soon as the method Dallas ends. Code is as follows:

public class Client
{
       public void ProcessDelegates()
       {
   MyFootballDelegate del= Dallas;
          iAsyncResult obj = del.BeginInvoke("cowboys",DallasCallback,null);   
 }
 
 private string Dallas(string team)
 {
          //do something here
          return string.format("{0} - {1}","Dallas", team);
        }
 
 //the callback method must have the following signature
 private void DallasCallback(IAsyncResult result)
 {
  //call to EndInvoke happens here and the result is obtained here
 }
}


NOTE:
In the code above, the Client specifies the method DallasCallback as the callback in the BeginInvoke call.So the thread from the thread pool that executes the Method Dallas,will also call the callback method as soon as the Dallas method completes. So the code in the DallasCallback method needs to be thread-safe.Besides, a certain amount of thread synchronization will be necessary to handle the interaction between the calling code and the delegate call/callback methods related code

The code in the callback method needs to call EndInvoke on the delegate as follows:


private void DallasCallback(IAsyncResult result)
{
 //call to EndInvoke happens here
 AsyncResult objreturn = (AsyncResult)result;
 MyFootballDelegate objDelegate = (MyFootballDelegate)objreturn.AsyncDelegate;

        //the value returned by method Dallas
 string result = objDelegate.EndInvoke(result); 
}

4/7/12

extending System.Linq.IOrderedEnumerable

Recently I was writing code to develop a web page that displayed a list of users. The page also had a drop down list containing the following sort
options:

Sort by last Name Descending
Sort by last Name ascending
Sort by Age descending
Sort by Age ascending
Sort by Activity Date desc
Sort by Activity Date asc
Sort by Login Date desc

The users have to be grouped by Location by default and then the selected sort was to be applied within each group.
The tricky business requirement was that if there is a tie while sorting by age or Last Name, the tied users had to be further sorted by Activity Date
descending and if there was still a tie, the users had to be sorted by Login Date descending.

Assume that the user decided to sort the default list using one of the options above. Let us call this variable "UserSort".
if the UserSort was "LastNameDesc" then we need to sort by the DB field called LastName.
if the UserSort was "LastNameDesc" then we need to sort by the DB field called LastName in descending order
if the UserSort was "Age" then we need to sort by the DB field called Age

So we need to determine the DB field to sort by, based on the user selection. We cannot do that using the existing OrderBy methods on IEnumerable
as shown below,since we do not know what field we will be sorting by.



IEnumerable lstUsers = GetUsers();
lstUsers = lstUsers.OrderBy(x=>x.Location) //default ordering
           .ThenOrderBy(WHAT FIELD DO WE SPECIFY HERE?)


This is where Extension methods come into play. following is the extension method on IOrderedEnumerable that enables us to add the required order
to the list based on the user's selected sort option.


public static IOrderedEnumerable ThenByCustomSort(this IOrderedEnumerable defaultList,string sortOrder)
{
switch(sortOrder)
{
case "LastNameDesc":
return defaultList.ThenByDescending(x=>x.LastName);
case "LastNameAsc":
return defaultList.ThenBy(x=>x.LastName);
case "AgeDesc":
return defaultList.ThenByDescending(x=>x.Age);
case "AgeAsc":
return defaultList.ThenBy(x=>x.Age);
case "ActivityDateDesc":
return defaultList.ThenByDescending(x=>x.ActivityDate);
case "ActivityDateAsc":
return defaultList.ThenBy(x=>x.ActivityDate);
case "LoginDateDesc":
return defaultList.ThenByDescending(x=>x.LoginDate);
default:
return defaultList;
}

}


This is how we add call this method:


IEnumerable lstUsers = GetUsers();
lstUsers = lstUsers.OrderBy(x=>x.Location)
           .ThenByCustomSort(UserSort);


Now coming to the tie in the results.We do something similar and create an extension method as shown below:


public static IOrderedEnumerable ThenByTieBreakSort(this IOrderedEnumerable defaultList, string sortOrder)
{ 
switch(sortOrder)
{
  case "LastNameDesc": 
  case "LastNameAsc":
  case "AgeDesc":
  case "AgeAsc":
   return defaultList.ThenByCustomSort("ActivityDateDesc").ThenByCustomSort("LoginDateDesc");
 case "ActivityDateDesc": 
  return defaultList.ThenByCustomSort("LoginDateDesc");
 default:
  return defaultList;
}
}


After adding the tiebreak the code looks now looks as shown below:


IEnumerable lstUsers = GetUsers();
lstUsers = lstUsers.OrderBy(x=>x.Location)
           .ThenByCustomSort(UserSort)
           .ThenByTieBreakSort(UserSort);

IMPORTANT:
Since LINQ queries are executed by means of deferred execution, we need to ensure that we are adding additional sort options well before the
query gets executed, which is exactly what the use of the extension methods above does.

NOTE:
I have used string data type for the sortOrder just for the purposes of blogging. It is better to use some strongly typed data type, like enums,
for the purpose. I have also not taken string casing into consideration.

Peace out.

2/13/12

Some more useful MVC grub

Assigning values to Action method parameters via OnActionExecuting handler

Let us say there is an action method as shown below:


[SetParameterValueFilter]
public ActionResult GetCityDetails([Bind(Prefix="MyCity")]string cityName)
{

 return View();

}


This method takes one string input parameter called "cityName" and returns a view.As you can see, the method is also decorated with a custom filter called "SetParameterValueFilter".

The purpose of this filter is to assign a value to the input parameter "cityName" of the action method GetCityDetails based on a certain condition X. So if the condition X is satisfied we will set the parameter value to "Dallas" else we will set it to "Houston".

We achieve this by overriding the OnActionExecuting method of the MVC framework that gets called before the GetCityDetails method gets called.

The code is as follows:


public class SetParameterValueFilterAttribute : ActionFilterAttribute
{  
   public override void OnActionExecuting(ActionExecutingContext context)
   {
     ParameterDescriptor[] ActionMethodParams = context.ActionDescriptor.GetParameters();

    //get the parameter that has a prefix 
    //of "MyCity" and set the value
     foreach (var param in ActionMethodParams)
     {
      if (param.BindingInfo.Prefix.ToUpper() == "MYCITY")
       {
          //set the parameter value
        if(ConditionX)
          context.ActionParameters[param.ParameterName] = "Dallas";
        else
          context.ActionParameters[param.ParameterName] = "Houston";
        break;
       }
     }
  }   
}

Some useful MVC grub

Changing the view name via the OnActionExecuted handler

Let us say there is an action method as shown below:


[ChangeViewFilter]
public ActionResult GetTeamDetails(string teamName)
{

 return View("DallasCowboys");

}

This method takes one input parameter called "teamName" and returns a view called "DallasCowboys".As you can see, the method is also decorated with a custom filter called "ChangeViewFilter".

The purpose of this filter is to change the View Name in the ActionResult of the GetTeamDetails method,if a certain condition X is satisfied. So if the condition X is satisfied we will change the View Name to "HoustonTexans" else we do nothing(the name remains "DallasCowboys").

We achieve this by overriding the OnActionExecuted method of the MVC framework that gets called after the GetTeamDetails gets called and before the View Engine is invoked. The code is as follows:


public class ChangeViewFilterAttribute : ActionFilterAttribute
 {
  public override void OnActionExecuted(ActionExecutedContext context)
    {
        //get the current view name
        string ViewName = ((ViewResultBase)(context.Result)).ViewName;

        //if the view name is not specified
     //it means the view name is the same as the action method name
        if (string.IsNullOrEmpty(ViewName))
            ViewName = context.ActionDescriptor.ActionName;

       if(ConditionX)
        ((ViewResultBase)(context.Result)).ViewName = "HoustonTexans";
    }
 }

2/11/12

Custom Model Binder in MVC

During postbacks, the MVC framework automatically binds the incoming data to the specified model. Let us say, you have a postback handler as show below:
 

  [HttpPost]
  public ActionResult MyPostbackHandler(Person person)
  {

  }
  
Assuming that your MVC view was bound to the Person object, when you postback to this method, the framework will automatically create an instance of Person and populate it with the values in the incoming form fields.

So if the Person object has a property called 'Location', the framework will look for a form field with the same name(Remember - "name" not "Id"). If it finds it, it will get the value from that form field and map it to the property. Same is the case with all the other properties and associated form fields. This is the Default MVC Model binding functionality.

 But what if our postback handler was as follows:

[HttpPost]
public ActionResult MyPostbackHandler(Dictionary<string,string> customObject)
{

}
In this case, default model binding will not work, since the method expects a dictionary object. We will have to explicitly extract the values from the incoming form fields and populate the dictionary object.

To do this we will need to create a custom model binder class as shown below.
Let us assume that we are going to only map fields whose names are prefixed with "Custom:"


public class CustomModelBinder : IModelBinder
{
    public object BindModel(ControllerContext cContext, ModelBindingContext bContext)
    {
        const string Prefix = "Custom:";
        string[] AllKeys = cContext.HttpContext.Request.Form.AllKeys;

        //1.get all the form fields with the specified prefix
        List CustomKeys = AllKeys.Where(x => x.StartsWith(Prefix)).ToList();

        var KeyValuePairs = new Dictionary();
        foreach (var key in CustomKeys)
        {
            ValueProviderResult objResult = bContext.ValueProvider.GetValue(key);
            //get the key's value
            string Value = objResult.AttemptedValue;

            //*Refer NOTE 1
            bContext.ModelState.SetModelValue(key, objResult);

            //*Refer NOTE 2
            if (!CusomValidator(Value))
                bContext.ModelState.AddModelError(key, "ErrorMessage");

            //add key and Value to dictionary
            KeyValuePairs.Add(key, Value);
        }
        return KeyValuePairs;
    }
}

NOTE 1
Before you add an error message for a key in modelstate, we must add it's ValueProviderResult(that contains the attempted value) to ModelState by calling SetModelValue. If we do not do that, the key has an associated error message, but does not have an attempted value to display in the front end. So if you use HtmlHelpers and the framework tries to set the attempted value when validation fails(by implicitly calling ModelState["key"].Value.AttemptedValue), it will throw a null exception since the Value is missing.

NOTE 2
Since we are not using default model binding, we cannot use DataAnnotations for Validation purposes, which means if the fields require some validation we will have to explicitly call the validation code and, if there are any errors, add them to ModelState.

Now that we have a custom model binder called CustomModelBinder, we need to tell the framework to use this custom model binder instead of the default one.We do it by adding the following attribute to the postback handler:


[HttpPost]
public ActionResult MyPostbackHandler([ModelBinder(typeof(CustomModelBinder))]Dictionary<string,string> customObject)
{

}

1/22/12

Good Application Development Practices

  • The core components of the application must be identified early and a significant amount of time and effort must be devoted to their design, development and testing. A perfect example of a core component is the Subscription functionality.
  • If possible, the smartest people must be assigned to these tasks.
  • Logging must be enforced in all important areas of the application. This ensures that we have enough diagnostic information to troubleshoot potential issues in production. Logging is also necessary to troubleshoot issues where the application might not be blowing up, but is not performing as intended.
  • The first page in the application that the user lands, after login, must not contain any time-consuming calls that can lead to page timeouts. This will prevent the user from logging into the application and accessing any other areas of the application.
  • Avoid Single Point of Failures. e.g. Do not use a single large object to share data across the whole application. e.g a cache object that stores a huge amount of data that might not be required by all areas of the application. Serialization and deserialization of a large object is a costly process and can slow down the entire application and may even bring the whole application to a halt.  
  • There should be a single point of access to all common objects used across the application. This ensures that the application behaves consistently. e.g. When trying to extract the one and only element from a common list, one part of the code must not call SingleOrDefault while another calls FirstOrDefault.
  • Be extremely cautious if your application uses a memory cache to store objects. When returning values from the cache, always return a deep copy of the object and not a shallow copy. This ensures that the calling code gets it's own copy of the cached data including all reference types. More importantly, this ensures that the calling code does not tamper with the original object in cache.
  • If  the application utilizes separate Read and Write databases, ensure that the database objects(e.g stored procedures) in either case return consistent results.

11/6/11

Deep copy & Shallow copy - Why basics matter

Recently, we ran into an issue in our application, a weird bug that was not easily reproducible. It goes like this:

When I try to look at data for User X, the application sometimes pulls up the details of X and sometimes it gets me the data for some other random User Y. There was no relation between X and Y. This was happening more under load and it was pretty difficult to reproduce.

After digging through the freaking code for hours and hours we finally figured out the problem.It happened for two reasons:

First Reason:
The programmer who wrote the code was careless or lacked a clear understanding of programming fundamentals.

Second Reason:
A shallow copy of the data was being returned instead of a deep copy.

Explanation:
We were using the memory cache to cache the common user metadata from the database so as to cut down the load on the database servers. We then created a class (a Singleton) to encapsulate the access to the cache. This class has an instance of a cache object that talks to the actual memory. The getters in this instance returned shallow copies of data i.e actual references to memory. It was the responsibility of the Singleton class to create a deep copy of the data before returning it to the calling code.

This critical piece of code was missing and so the Singleton was essentially returning a reference to the data in cache.The code that called the Singleton was then modifying the shallow copy of the metadata, unaware that it was actually modifying the values in cache. So when User Y requested data, since the class was a singleton(and therefore using the same cache instance as well), it was returning a modified version of the metadata. When this metadata was combined with other data, specific to user Y, it resulted in weird values and as a result the user ended up seeing some other data.

Solution:
The fix was very simple. In the Singleton class, we had to create a deep copy of the object returned from the cache, before passing it to the calling code, so any changes made to that object did not impact the original values in cache.