Tuesday 11 November 2014

Five Great .NET Framework 4.5 Features

It has been almost a year since .NET 4.5 got released. But the problems with most of the recent Microsoft releases have been communication with .NET developers. Only one or two features are known to developers and other features just stay on MSDN and end up becoming simple documents.

Feature 1: async and await (code markers)
This feature has been oversold and every .NET evangelist has talked about it.





Let us try to make sense of the above statement by understanding the below code. If you see the flow of the below code:
  1. Method() gets called from the Static void main() entry point.
  2. Method() spawns a Task (thread) LongTask which waits for 10 seconds.
  3. At the same time the control comes back to Method() to execute the remaining code after the task was called. In other words as the invocation is multi-threaded (Task.Run…),  LongTask is also running i.e., waiting for 10 seconds and the remaining code of your Method() is also executed.
Now in certain scenarios we want step 3 to behave differently. We want that after LongTask() finishes execution, the control should go back to Method to execute the remaining code. The async and await keywords help to achieve the above behavior.



Now that you have read about “async” and “await”, let me put a cross question. The above behavior can be also achieved by using Task.Wait or Task.ContinueWith, so how do they differ? I am leaving this question as a home work for you.

Feature 2: Zip facility (Zip compression)
Zip is one of the most accepted archive file formats. Zip format is supported in almost all operating systems with some built-in name.
  • In Windows operating system it’s implemented by the name “Compressed folders”.
  • In MAC OS it’s implemented by the name “Archive utility”.
Now in .NET we did not have built-in support for implementing Zip compression. Many developers where using third party components like “DotnetZip”. In .NET 4.5, the Zip feature is baked in the framework itself, inside the namespace System.IO.Compression.
The first step is you need to reference two namespaces:
  • System.IO.Compression.FileSystem
  • System.IO.Compression
The next step is to import the below two namespaces:
using System.IO.Compression;
If you want to Zip files from a folder you can use the CreateFromDirectory function as shown below.
ZipFile.CreateFromDirectory(@"D:\data",@"D:\data.zip");
If you wish to unzip, you can use the ExtractToDirectory function as shown in the below code.
ZipFile.ExtractToDirectory(@"D:\data.zip", @"D:\data\unzip");

Feature 3: Regex timeout (TimeOut)

Regex” has been the most preferred way of doing validations.. But because of the typical parsing logic of regex it is exposed to DOS attacks.For instance consider this regular expression - “^(\d+)$”. This regex expression says that it can have only numbers. if we want to validate “123456X”. It will have six paths.But if we add one more number to it, it will take seven paths. In other words as the length increases a regex takes more time to evaluate. In other words the time taken to evaluate is linearly proportional to the length of the characters.Now let’s complicate the previously defined regex from “^(\d+)$” to “^(\d+)+$. If we now try to validate “123456X”, it will run through 32 paths. If you add one more character the number pf paths become 64.


This linear rise of evaluation time can be exploited by hackers to do a DOS (Denial of Service) attack. They can put a long, a really long string and make your application hang forever.
The proper solution for this would be to have a timeout on the regex operation. Good news, in .NET 4.5 you can now define a timeout property as shown in the below code.


try
{
  var regEx = new Regex(@”^(\d+)+$”, RegexOptions.Singleline, TimeSpan.FromSeconds(2));
  var match = regEx.Match(“123453109839109283090492309480329489812093809x”);
}
catch (RegexMatchTimeoutException ex) { Console.WriteLine(“Regex Timeout”); }

Feature 4: Profile optimization (Improved startup performance)


We all know .NET code is in a half compiled format. During runtime, the JIT (Just-in-Time) compiler runs and translates this half compiled IL code to native machine code. One of the big complaints about JIT is that when a .NET applications runs the first time, it runs slow as JIT is busy translating IL code to machine code.
In order to bring down this startup time, in .NET 4.5, we have something called “profile optimization”. Profile is nothing but a simple file which has a list of methods which the application will need during startup. So when the application starts, a background JIT runs and starts translating IL code for those methods into machine / native code.
This background JIT compilation of startup methods happens across multiple processors thus minimizing the start up time further. Also note you need to have a multicore box to implement profile optimization. In case you do not have a multicore box then this setting is ignored.


In order to create the “profile” file, you first need to import the System.Runtime namespace. You can then call the SetProfileRoot and StartProfile methods of the static class ProfileOptimization. Now when the application starts the background JIT it will read from the profile file and compile your start up methods in the background thus reducing your startup time.


Feature 5: Garbage collector (GC background cleanup)

Garbage collector is one real heavy task in a .NET application. And it becomes heavier when it is an ASP.NET application. ASP.NET applications run on the server and a lot of clients send requests to the server thus creating loads of objects, making the GC really work hard for cleaning up unwanted objects.

In .NET  4.0, when the GC runs for cleanup, all the application threads are suspended.

In server GC there is one more thread created which runs in the background. This thread works in the background and keeps cleaning generation

To enable server GC, we need to use the gcServer XML tag and enable it to true.
<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>