Wednesday, 12 August 2015

Thread Synchronization with SpinLock and How to Implement it in C# & VB

Ever face a situation where you need to access a value concurrently and prevent race condition from happening. For your application that deals with multiple threads and every threads needs to have exclusive right to change the value, there are a few kinds of lock that can be used. For more details on the list of available locks, you can refer to the following link https://msdn.microsoft.com/en-us/library/ms228964(v=vs.110).aspx

For now we will look into SpinLock. What Spinlock does is that if thread [A] has attain the lock, other threads will just wait for the thread [A] to release the lock. While waiting for the thread [A] to release the lock, the spinlock will just spin in the loop until the lock is being release by the thread [A].

Due to this, SpinLock is only suitable if the lock is being held in a very short duration. Acquiring the lock for a long duration will reduce the performance of other applications since more CPU cycles is being used. Also, it is a waste of CPU time to held the lock for a long duration, since it basically just do nothing other than loop until the lock is available.

So, before we look into how to use SpinLock, make sure your project is targeting .NET Framework version 4 and above.

Implementing SpinLock is pretty easy and straight forward. Firstly, you need to have an instance of SpinLock to get started.

[C#]
SpinLock spinLock = new SpinLock();

[VB]
Dim spinLock As SpinLock = New SpinLock()


The isLocked variable, which is a boolean variable, is to define whether the thread owns the lock. isLocked variable needs to be declared as a local variable, so that the value don't get overwrite by other threads.

[C#]
bool isLocked = false;

[VB]
Dim isLocked As Boolean = False


spinlock.Enter is to acquire the lock and wait for the lock to be released if is owned by other thread.

[C#]
spinLock.Enter(ref isLocked);

[VB]
spinLock.Enter(isLocked)


spinlock.Exit is to release the lock and to enable other threads to acquire the lock.

[C#]
spinLock.Exit();

[VB]
spinLock.Exit()


So let's take an example where you would like to have a multiple threads accessing a value from a variable and at the same time need to ensure that race condition did not happen. To prove that race condition did not happen with SpinLock, I have created a simple sample in a console to demonstrate this. Assuming the following method is to increase the value of an integer. To prevent other threads from accessing the variable _valueWithLock, the method is being implemented it with SpinLock.

[C#]
private static void ChangeValueWithSpinLock()
{
    var isLocked = false;
    try
    {
        _spinLock.Enter(ref isLocked);
        _valueWithLock++;
    }
    finally
    {
        if (isLocked)
        {
            _spinLock.Exit();
        }
    }
}

[VB]
Private Sub ChangeValueWithSpinLock()
    Dim isLocked As Boolean = False

    Try
        _spinLock.Enter(isLocked)
        _valueWithLock += 1
    Finally
        If isLocked Then
            _spinLock.Exit()
        End If
    End Try
End Sub

To simulate multiple threads accessing the method, a Parallel class is being used. It will loop and call the methods 1000000 times.

[C#]
Parallel.For(0, 1000000, (i) => {
    ChangeValue();
});

[VB]
Parallel.For(0, 1000000, New Action(Of Integer)(Sub()
                                                    ChangeValue()
                                                End Sub))

By running the codes, you will notice that the value will increase to 1000000. Which means no race condition occurred. 

The sample project can be obtained here. https://1drv.ms/u/s!Aj2AA7hoIWHmgmKoweIKoaf5z9hf




Tuesday, 10 February 2015

Unnecessary Try Catch Block Affects Application Performance in C# & VB

It is quite common to use a try catch block to handle the exception thrown by the application. It can be for saving the exception details for debugging purposes or to hide the exception from displaying to the end users and replace it with a more user friendly messages. But blindly use it will affect the application performance.

Let's take a look of an example of how the application's performance get affected from adding unnecessary try catch block by comparing rethrow an exception back to caller & letting the exception flow back to the caller. We will do a performance comparison between both of them with a Stopwatch class.

I have a method that catch the exception and rethrow it back to caller without doing anything in the catch block.
[C#]
private void IntendedException()
{
    try
    {
        throw new ApplicationException("Throw exception with catch");
    }
    catch (ApplicationException)
    {
        throw;
    }
}

[VB]
Private Sub IntendedException()
    Try
        Throw New ApplicationException("Throw exception with catch")
    Catch ex As Exception
        Throw
    End Try
End Sub


This is another method that just let the exception flow back to caller.
[C#]
private void IntendedExceptionWithoutCatch()
{
    throw new ApplicationException("Throw exception without catch");
}

[VB]
Private Sub IntendedExceptionWithoutCatch()
    Throw New ApplicationException("Throw exception with catch")
End Sub

Then in the console application, we will do a 2000 loop and check how long it takes to complete the execution with Stopwatch.

[C#]
Stopwatch sw = new Stopwatch();

sw.Start();

for (int i = 1; i <= 2000; i++)
{
    try
    {
        IntendedException();
    }
    catch (Exception)
    {
        // Do stuff here.
    }
}

sw.Stop();
Console.WriteLine(string.Format("IntendedException {0}", sw.Elapsed.TotalMilliseconds));
sw.Reset();
sw.Start();

for (int i = 1; i <= 2000; i++)
{
    try
    {
        IntendedExceptionWithoutCatch();
    }
    catch (Exception)
    {
        // Do stuff here.
    }
}
sw.Stop();

Console.WriteLine(string.Format("IntendedExceptionWithoutCatch {0}", sw.Elapsed.TotalMilliseconds));
Console.ReadKey();

[VB]
Dim sw As Stopwatch = New Stopwatch()

sw.Start()

For i As Integer = 1 To 2000
    Try
        IntendedException()
    Catch ex As Exception
        ' Do something here.
    End Try
Next

sw.Stop()
Console.WriteLine(String.Format("IntendedException {0}", sw.Elapsed.TotalMilliseconds))
sw.Reset()
sw.Start()

For i As Integer = 1 To 2000
    Try
        IntendedExceptionWithoutCatch()
    Catch ex As Exception
        ' Do something here.
    End Try
Next

sw.Stop()
Console.WriteLine(String.Format("IntendedExceptionWithoutCatch {0}", sw.Elapsed.TotalMilliseconds))
Console.ReadKey()

Execute the above code will get the following result. (The result varies depending on the machine that it runs on, debug mode and release mode)
IntendedException 37.6998ms
IntendedExceptionWithoutCatch 18.7001ms

As you can see from the above result, it will perform better with lesser try catch block. But that does not mean that we have to scrap off all the try catch block in your code, just have to use it wisely and not simply use it in every section of your code. Based on the above example, if the catch is not doing anything, then just let it flow back to the caller to handle the exception.

Here's the source code: https://onedrive.live.com/redir?resid=E6612168B803803D!352&authkey=!AHy5NurawlsrM7Q&ithint=file%2czip

Sunday, 7 September 2014

Create Simple Windows Service and Self Install in C# & VB

Feeling troublesome for using installutil to install Windows Service? Having to navigate to C:\Windows\Microsoft.NET\Framework\<your framework version> or C:\Windows\Microsoft.NET\Framework64\<your framework version> just to install or uninstalling Windows Service in server environment? Well, there's a more convenient way to perform installation and uninstallation, which is to write code for the Windows Service to self install / uninstall.

Before we go into that, let's create a simple Windows Service Project.

1) Select Windows Service and fill up your desired project name.

Visual Studio 2013 New Project


2) For this demo, Timer will be used to write to event log for every 10 seconds. So, open up the service in View Code mode or click on F7. 

Include the following namespace
[C#]
using System.Timers;
using System.Diagnostics;

[VB]
Imports System.Timers
Imports System.Diagnostics


Create a Timer variable
[C#]
private Timer _timer = null;

[VB]
Private _timer As Timer


OnStart Method - Initialize the timer that will write to event log for every 10 seconds. This method will run when the service started.
[C#]
_timer = new Timer();
_timer.Enabled = true;
_timer.Interval = 10000;
_timer.Elapsed += (sender, e) => {
    EventLog eventLog = new EventLog();
    eventLog.Source = "Windows Service Self Install Demo";
    eventLog.WriteEntry(DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") + " - Windows Service Self Install Demo.");
};

[VB]
_timer = New Timer
_timer.Enabled = True
_timer.Interval = 10000

AddHandler _timer.Elapsed, AddressOf OnTimedEvent


Private Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
        Dim eventLog As EventLog = New EventLog()
        eventLog.Source = "Windows Service Self Install Demo VB"
        eventLog.WriteEntry(DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") + " - Windows Service Self Install Demo.")
End Sub


OnStop Method - To stop and release resource used by the timer. This method will run when the service is stopped.
[C#]
_timer.Close();

[VB]
_timer.Close()


3) Create a ProjectInstaller by double click or shift + F7 or open service in View Designer mode, right click on any gray area and click Add Installer. A ProjectInstaller file will be created in your project.

Windows Service Designer

4) Double click or shift + F7 or open ProjectInstaller in View Designer mode. Choose your desired properties for both serviceProcessInstaller1 and serviceInstaller1. In my case, this is what i set.

serviceProcessInstaller1
- Account : LocalSystem

serviceInstaller1
- StartType : Automatic
- Description : Demo Self Install Windows Service
- DisplayName : Windows Service Demo
- ServiceName : Windows Service Demo

Service Process Installer

Service Installer


With this, the windows service is created. Next would be to create a self install windows service. In the main method, add the following lines of code to pass in argument. In C# the main method is located in "Program.cs" file, whereas for VB, it is located in your service file.


[C#]
if (System.Environment.UserInteractive)
{
    if (args.Count() == 1)
    {
        if (args[0] == "-install")
            ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });

        if (args[0] == "-uninstall")
            ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
    }
    return;
}

[VB]
If System.Environment.UserInteractive Then
    If args.Count() = 1 Then
        If args(0) = "-install" Then
            ManagedInstallerClass.InstallHelper(New String() {Assembly.GetExecutingAssembly().Location})
        End If

        If args(0) = "-uninstall" Then
            ManagedInstallerClass.InstallHelper(New String() {"/u", Assembly.GetExecutingAssembly().Location})
        End If
    End If
    Exit Sub
End If


Once it is done, compile your project. Next is to show how to install or uninstall the windows service. Here are the couple of ways to install / uninstall the windows service.


[Command Prompt]
1) In command prompt window, navigate to your bin folder that contain the service executable file. 

2) To install, type and run [Windows Service Assembly Name].exe -install. To uninstall, just change -install to -uninstall and execute.


path.exe -install

path.exe -uninstall


[Shortcut]
1) Navigate to your bin folder that contain the service executable file. 

2) Create a shortcut from the service executable file. Right click on it and select Properties

3) Select Shortcut tab.

4) In the target field, for installation, add -install after your executable path. For uninstallation, just change -install to -uninstall or you can create 2 different shortcut for install and uninstall respectively.

5) Run the shortcut.

path -install

path.exe -uninstall


[Visual Studio]
1) Right click on your Windows Service project and click Properties.

2) Select Debug tab.

3) Under Start Options. For installation, type -install in Command line arguments field. For uninstallation, just change -install to -uninstall.

4) Start / debug your project.

-install

-uninstall


By using one of the methods above to install, the windows service should appear in the Service window. If you are unsure how to open the service window, you can do one of the following.
- At Run window, Type services.msc and click OK button, or
- Control Panel > Administrative Tools > Services.

Services Window

That's all for creating a Self Install.

Here's the source code : https://onedrive.live.com/redir?resid=E6612168B803803D!358&authkey=!AE6WfmdHMIoWpTg&ithint=file%2czip

If you would like to find out more on what else you can do during Self Install other than just installing windows service, then you may want to consider take a look here http://jaryl-lan.blogspot.com/2015/11/list-of-additional-funtionality-to.html

Sunday, 10 August 2014

[LocalDB] Connecting to LocalDB failed [Error Code 52]

Have you been using LocalDB for your development machine and it works perfectly fine. But when you deploy your application together with LocalDB to another machine, it just failed to connect to the LocalDB.

You may see a similar error message as follows.

System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)

What the above message meant is that the machine you deployed does not have a Local Database Runtime installed. So before we proceed to solve the above issue, let's look through certain things.

If your localDB is created from Visual Studio 2013, then your localDB would have version 11.0. To view the version in detail, just execute the query "SELECT @@VERSION". You can execute the query through SQL Server Management Studio or Visual Studio 2013.

Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
    Oct 19 2012 13:38:57
    Copyright (c) Microsoft Corporation
    Express Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)

Next, we have to download the SqlLocalDB.msi from http://www.microsoft.com/en-us/download/details.aspx?id=29062. Depending on your server machine, pick 32Bit or 64Bit.

If your LocalDB version is version 12.0 or SQL Server 2014, then you may need to get the SqlLocalDB.msi from this link instead http://www.microsoft.com/en-my/download/details.aspx?id=42299.

UPDATE: With the release of SQL Server 2016, you can now get the LocalDB version 13.0 here https://www.microsoft.com/en-us/download/details.aspx?id=52679.

After you have downloaded it, install it to the machine that contains your application that is facing the above error. The installation is pretty much straightforward and remember to read the terms and condition before proceed with the installation

After you have done the installation, your application should now be able to connect to the LocalDB.

For more details : http://www.mssqltips.com/sqlservertip/2694/getting-started-with-sql-server-2012-express-localdb/

If you do hit with another error when your web application is deployed to IIS and is accessing to LocalDB, you may want to check it out here http://jaryl-lan.blogspot.com/2016/06/localdb-connecting-to-localdb-failed.html