Tuesday, May 27, 2014

Decompiling BAML

We know that XAML is a declarative markup language. XAML simplifies creating a UI for .NET application created using WPF or Silverlight. It is simple and easy to create UI elements using XAML, and then separate the design from run-time logic by using code-behind files, joined to the markup by partial class definitions. So what is a BAML ?

BAML is the short form of Binary Application Markup Language, as the name implies it is a binary representation of the XAML file containing implementation details. It is nothing but  parsed, tokenism and XAML that is converted into binary format. Tokenized  means lengthier bits of XAML are replaced with shorter tokens. It is compressed declarative format that is faster to load and parse also it is smaller in size as compared to regular XAML.

So when you compile a WPF project, all XAML files whose build action are set to Page or Resource gets converted to BAML and then embedded as resource in the assembly. So now you have a binary object that is smaller and also optimized in a way that makes it faster to parse at runtime. BAML gets embedded as a resource so developer don't need to worry about linking,parsing or referencing anything  except calling InitializeComponent() in code-behind.

BAML is converted to implementation code during runtime, internally it is used for creating objects. If  you set the x:shared attribute to false, a new copy is created from the BAML every time you use the object. In earlier versions developers didn't have access to BAML, After WPF 4 the new implementation of XamlReader.Load(), BAML loading, Control & DataTemplates functionality with a new engine built on top of the new System.Xaml.dll, I know back in the early days of WPF that CAML was generated rather than BAML, looks like the WPF team has decided to eliminate it, and keep the BAML version.

Baml2006Reader :
Again as most of us know that in WPF, UI can be created either by code or by XAML-which is basically an declarative XML to describe object graphs. This approach makes UI development  easy and fast but parsing XAML file at runtime is quite expensive. So the MarkupCompiler converts the XAML file to BAML.The BAML API is something unique of WPF and was not public until .NET 4.0. Now it's available through the Baml2006Reader implementation. The following code shows how to load a BAML stream .Baml2006Reader uses Reflection to load the assemblies needed for decompilation, which is a little expensive.
var reader = new Baml2006Reader(stream);
var writer = new XamlObjectWriter(reader.SchemaContext);
while(reader.Read())
{
    writer.WriteNode(reader);
}
return writer.Result;
A simple way to decompile the generated BAML is by using the dotPeek from JetBrains or .NET Reflector. Lets walk through the process of installing the plugin.

dotPeek : We have to build and install a plugin for dotPeek. To install the plugin follow this steps.
  1. Download the addin Baml4dotPeek  from the github project https://github.com/cprieto/Baml4dotPeek
  2. Build the project, you might have to update reference to point to your dotPeek bin folder.
  3. A successful  build will generate a output file "BamlFromResource.dll".
  4. Copy this file to the dotpeek bin directory.
  5. Restart dotPeek, and verify form the Tools|Options, if you have the BamlDecompiler.



Once you have the plugin installed open any WFP project and expand the directory tree to find the resources . From the resources you will find some baml file, select any file and the window on the right will display the xaml for that resource.




Note: For Silverlight the XAML files are not converted in to BAML.When you build a Silverlight project a .xap file is created, it is just a .zip-file containing an AppManifest.XAML and all resources in your project compiled as dll's.  You can verify that by opening a dll in dotPeek or Reflector, it will show the XAML-files and other resources.

Thursday, February 13, 2014

Async task helper


Here is a simple helper class for async tasks. The helper class encapsulates code for creating task, This is a very interesting way to isolate the complexity of task programming. Class implementation is nothing much fancy, Async and await keywords are only used in the helper class so our main code remains very clean. The method DoAsync accepts three parameters, one function and two action. First is the function that is the actual work or task we want to accomplish asynchronously, second action is fired when the work is completed successfully and the third parameter is a action that is fired in case of an exception.

   1: using System;
   2: using System.Threading.Tasks;
   3:  
   4: namespace Common.Helper
   5: {
   6:     public class TaskHelper
   7:     {
   8:         public static void DoAsync<T>(Func<T> work, Action<T> completed, Action<Exception> exceptionHandler)
   9:         {
  10:             Task<T> task = AsyncTask(work);
  11:             task.GetAwaiter().OnCompleted(() =>
  12:             {
  13:                 if (task.IsFaulted)
  14:                     exceptionHandler(task.Exception);
  15:                 else
  16:                     completed.Invoke(task.Result);
  17:             });
  18:         }
  19:  
  20:         private static async Task<T> AsyncTask<T>(Func<T> func)
  21:         {
  22:             return await Task.Run(func);
  23:         } 
  24:     }
  25: }

 

Below is a very simple class that utilize TaskHelper. Assuming that we are using the class in a UI application to perform some lengthy work, once the work is complete we want to display some data to the user. The method DoWork is suppose to perform the lengthy work and return the result as a string value. Once the work is finish the method WorkCompleted will be invoked, if there are any exception during this process the method HandleException should handle and display proper error to the user.

 


   1: public class SomeTask
   2: {
   3:     public SomeTask()
   4:     {
   5:         TaskHelper.DoAsync<string>(DoWork, WorkCompleted, HandleException); 
   6:     }
   7:     private string DoWork()
   8:     {
   9:         return "TaskDone";
  10:     }
  11:     private void WorkCompleted(string status)
  12:     {
  13:     }
  14:     private void HandleException(Exception ex)
  15:     {               
  16:     }
  17: }

Friday, July 12, 2013

Using StopWatch to calibrate code performance


When we have to calibrate the performance of a loop, method or block of code we quickly tend to throw in few datetime.now and calculate the time difference. This approach has some flaws and does not provide accurate results. One major reason is datetime.now has a very low resolution depending on the computer, a typical computer has a resolution of somewhere around 100 ticks per second.

Microsoft introduced the Stopwatch class to help developers get more accurate time stamp. Stopwatch is generally more precise then datetime.now and secondly it’s more lightweight, also it support object oriented design. So what does the stopwatch class do, It just stores the current time-stamp (via QueryPerformanceCounter) when you start it, and compare it to the time-stamp when you stop it, so between start and stop it does not use cpu cycles and so it does not effect the performance of your code. Stopwatch was designed specifically for accurate time measurements, so you can be sure it is optimized. Though it would be a good idea to remove any performance counters in a release build. It is also much more accurate than comparing successive values of datetime.now.

For everyday debugging use case we need a easy and clean code to calculate execution time, so lets create a re-usable class that can be easily used to measure performance of our code.


   1: using System;
   2: using System.Diagnostics;
   3:  
   4: namespace Common.Helper
   5: {
   6:     public class StopWatchHelper
   7:     {
   8:         public static void CalculateTime(string stopWatchLabel, Action action)
   9:         {
  10:             var internalStopWatch = new InternalStopWatch();
  11:             action();
  12:             PrintToConsole(internalStopWatch.TimeDifference(), null, stopWatchLabel);
  13:         }
  14:  
  15:         public static void CalculateTime(Action action)
  16:         {
  17:             var internalStopWatch = new InternalStopWatch();
  18:             action();
  19:             PrintToConsole(internalStopWatch.TimeDifference(), action.Method.Name, null,
  20:                            new StackTrace(new StackFrame(1, true)));
  21:         }
  22:  
  23:         private static void PrintToConsole(TimeSpan timeDifference, string methodName = null,
  24:                                            string stopWatchLabel = null, StackTrace st = null)
  25:         {
  26:             if (string.IsNullOrEmpty(stopWatchLabel))
  27:             {
  28:                 PrintDottedLine();
  29:                 Console.WriteLine(" Method : {0} ", methodName);
  30:                 Console.WriteLine(" Time : {0} ", timeDifference);
  31:                 Console.WriteLine(" Location: {0}", st);
  32:                 PrintDottedLine();
  33:             }
  34:             else
  35:             {
  36:                 PrintDottedLine();
  37:                 Console.WriteLine(" Label : {0} ", stopWatchLabel);
  38:                 Console.WriteLine(" Time : {0} ", timeDifference);
  39:                 PrintDottedLine();
  40:             }
  41:         }
  42:  
  43:         private static void PrintDottedLine()
  44:         {
  45:             Console.WriteLine("-------------------------------------------------\n");
  46:         }
  47:  
  48:     }
  49:  
  50:     internal class InternalStopWatch
  51:     {
  52:         private readonly Stopwatch stopwatch;
  53:  
  54:         public InternalStopWatch()
  55:         {
  56:             stopwatch = new Stopwatch();
  57:             stopwatch.Start();
  58:         }
  59:  
  60:         public TimeSpan TimeDifference()
  61:         {
  62:             stopwatch.Stop();
  63:             return stopwatch.Elapsed;
  64:         }
  65:  
  66:     }
  67:  
  68: }



Code for the main console application

   1: using System;
   2: using System.Collections.Generic;
   3: using Common.Helper;
   4:  
   5: namespace StopWatchHelperConsole
   6: {
   7:     internal class Program
   8:     {
   9:         private static void Main(string[] args)
  10:         {
  11:             //If not release mode then exit the application
  12:             if (!CheckIfReleaseMode()) return;
  13:  
  14:             //Single line statment
  15:             var list = CreateNewList();
  16:             StopWatchHelper.CalculateTime(list.Sort);
  17:  
  18:             //Use Lambda
  19:             list = CreateNewList();
  20:             StopWatchHelper.CalculateTime(() =&gt; { list.Sort(); });
  21:  
  22:             //User a label to indicate the location
  23:             list = CreateNewList();
  24:             StopWatchHelper.CalculateTime("StopWatch for List", () =&gt;
  25:                 {
  26:                     list.Sort();
  27:                     list.Sort();
  28:                 });
  29:  
  30:             Console.Read();
  31:         }
  32:  
  33:         private static List CreateNewList()
  34:         {
  35:             var list = new List();
  36:             const int size = 10000;
  37:             var random = new Random();
  38:             for (int i = 0; i &lt; size; ++i)
  39:                 list.Add(random.Next());
  40:             return list;
  41:         }
  42:  
  43:         private static bool CheckIfReleaseMode()
  44:         {
  45: #if DEBUG
  46:             Console.WriteLine("Performance test should be done in Relase Mode");
  47:             Console.Read();
  48:             return false;
  49: #else
  50:             return true;
  51: #endif
  52:         }
  53:     
  54:     }



Output on the console screen

Console Output