Wednesday, March 17, 2010

A Smarter ViewModelBase

The advent of WPF has led to ubiquity of the MVVM pattern. Developers usually have a ViewModelBase class the implements the INotifyPropertyChanged interface as shown below:-

class ViewModelBase : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   protected void NotifyPropertyChanged(string propertyName)
   {
      if (propertyName != null)
      {
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
      }
   }
}

The NotifyPropertChanged method is called from within the "set accessor" of a property with the name of the property passed as a parameter.

The problem with this implementation is that if the property name "string" parameter has be be in sync with actual property name as an when it changes. We as developers are prone to spelling mistakes and could easily leave out some property change notifications out of sync with the property name.

The following code address the problem mentioned above

class ViewModelBase : INotifyPropertyChanged
{
   private const string SetPropertyPrefix = "set_";

   #region INotifyPropertyChanged Members

   public event PropertyChangedEventHandler PropertyChanged;

   #endregion

   // Call this method from within a set accessor of a property
   protected void NotifyCurrentPropertyChanged()
   {
      if (PropertyChanged == null)
      {
         return;
      }

      StackTrace st = new StackTrace(1);
      StackFrame sf = st.GetFrame(0);
      MethodBase mb = sf.GetMethod();

      if (mb.MemberType == MemberTypes.Property)
      {
         // if the calling method is not an accessor of a property, do nothing
         string methodName = mb.Name;
         if (methodName.StartsWith(ViewModelBase.SetPropertyPrefix))
         {
            // We are bothered only with set accessors
            string propertyName = methodName.Substring(ViewModelBase.SetPropertyPrefix.Length);
            NotifyPropertyChanged(propertyName);
         }
      }
   }

   // The conventional NotifyPropertyChanged
   protected void NotifyPropertyChanged(string propertyName)
   {
      if (PropertyChanged != null)
      {
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
   }
}

The NotifyCurrentPropertyChanged method can be used in the set accessors of properties. Note that there is no need to pass the propery name anymore!

Tuesday, March 16, 2010

Thread.Suspend – Don’t call me anymore

Recently I ported our project from .NET 3.5 to .NET 3.5 SP1. Among the bunch of warnings, I found these interesting (to write about):-

Thread.Suspend has been deprecated. Please use other classes in System.Threading, such
as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.
http://go.microsoft.com/fwlink/?linkid=14202

Thread.Resume has been deprecated. Please use other classes in System.Threading, such
as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.
http://go.microsoft.com/fwlink/?linkid=14202"

I had used the Thread.Suspend and Thread.Resume APIs in order to freeze operation (interaction with hardware) until the desired user input is received to continue. This is not a rogue programming model. In the Win32 world, despite the caveats raised for SuspendThread and ResumeThread, these APIs are not uncommon for tough guys. I have used it in my earlier projects. But it seems, in .NET world, we have to infer something from the above warnings. These native and low-level APIs seem to have some serious implications. My interpretation of this warning is Microsoft is not going to support this API anymore. Since the threading and runtime infrastructure is always undergoing (internal) changes, it seems to have a strong bearing on the behavior of the API. Besides, CLR thread may not be a Win32 thread physically. I have read that the CLR may use fibers, if possible. So the CLR safely withdraws from providing any more guarantees for platform specific low-level APIs.

Now Let’s see what are the implications of using this API in our code

With Thread.Suspend, we have explicit control over the execution of an arbitrary thread which is absolutely a dangerous thing. Thread.Suspend/Resume are very primitive and low level APIs to be used control the flow of a program. A thread may be executing any piece of code when it is being suspended, It may be executing a user code or an operating system code at the User-Level IRQL or in a third-party library. Under these situations, the caller of Thread.Suspend is totally oblivious of the fact that the thread might be holding synchronization locks that are critical to the application/library and OS. This could result in deadlocks that are difficult to debug. All this is pointing towards one thing, an application is not well designed if it is using these APIs.

If we want to synchronize threads, we should always resort to understanding the problem first and design a solution with the higher primitives provided by the framework like Mutex, Semaphores, critical sections and events etc; that is what is suggested by .NET with the above warnings. By using these high-level primitives, we delegate the lower-level responsibilities of suspending and resuming the threads to the Framework/OS. Besides making our code safe, we make our intent explicit. A few lines of explicit code is worth a ton of documentation!