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  block of code, loop or method usually we usually tend to quickly trow in the datetime.now and calculate the time difference. This approach has some flaws and does not provide accurate results. One reason is that the 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 get more accurate time stamp. Stopwatch is generally more precise then datetime.now and secondly it’s more lightweight, also it support object oriented.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 current time-stamp when you stop it, so between start and stop it does not use cpu cycles and so it does not affect performance of your code. Though it would be a good idea to remove any performance counters in a release build. Stopwatch was designed specifically for accurate time measurements, so you can be sure it is optimized.It is also much more accurate than comparing successive values of datetime.now.

 For daily use we need a clean and easy way to calculate execution time of our code, so lets create a re-usable class that we can use 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






















Friday, July 6, 2012

c# readonly vs constant in different assembly

In C#/.NET we can declare a constant value by either using keyword 'const' or 'readonly' . Using const keyword will define compile time constant and readonly will define runtime. Only the C# built-in types can be declared using 'const' for user-defined types like class, struct or array use 'readonly'. Compiler will have a literal value for all the fields that declared const, so if you decompile the code you will find no reference to the constant but actual value. Compile time constant are faster then readonly but are less flexible and can create issues if not used properly. As a general rule one should strictly use compile time constant only for values that are never going to change for example defining value of PI, any value that might change in future use readonly.

During developing a large application there are numerous scenario where you might have to choose between compile-time and run-time constant's. Compile time constants are faster then run-time, although in certain conditions to avoid potential problems you might want to consider using run-time constants . The difference between the two is more clearly explained in this post [ linky ]

Here is an practical example, two teams are working on a same project one team develops a external class library and other team develops the main application. Team one has developed the class library that has some const and readonly variables, these values are consumed in the application developed by the team two. If in future team one updates the constant value in the external class library and the application is not recompiled it would not reflect the new value. This issue is only created if your are using constant values form external assemblies. If a const value changes in a assembly then you need to rebuild all the clients applications dependent on it.




   1:  using System;
   2:  using ExternalLibrary;
   3:   
   4:  namespace ExternalLibrary
   5:  {
   6:      public class ConstantLib
   7:      {
   8:          public static readonly int StartValue = 105;
   9:          public const int EndValue = 120;
  10:          public readonly int ReadonlyValue = 555;
  11:      }
  12:  }
  13:   
  14:   
  15:   
  16:  namespace CTvsRT
  17:  {
  18:     class Program
  19:     {
  20:        static void Main(string[] args)
  21:        {
  22:         ConstantLib cl = new ConstantLib();
  23:   
  24:         Console.WriteLine("ConstantLib.StartValue {0}", ConstantLib.StartValue.ToString());
  25:         Console.WriteLine("ConstantLib.EndValue {0}", ConstantLib.EndValue.ToString());
  26:         Console.WriteLine("ConstantLib.readonlyValue {0}", cl.ReadonlyValue.ToString());
  27:   
  28:         Console.Read();
  29:        }
  30:     }
  31:  }