Friday, November 30, 2018

Thread safety when using static properties/fields inside functions


When using static properties inside functions you have to make sure that the properties are modified in a thread safe manner. If not this could cause exceptions or unexpected behavior in the application.

In the below example changing the static field will cause exception/incorrect behavior if accessed by multiple threads/processes.

public class MyClass
{
    public static List<int> lst = new List<int>();

    //DoWork with no lock will cause the application to fail
    public int DoWork()
    {
        try
        {
            Console.WriteLine("Work started");
            Thread.Sleep(100);
            lst.Add(100);
            Thread.Sleep(100);
            lst.Add(200);
            Thread.Sleep(100);
            lst.Add(300);
            Thread.Sleep(100);
            lst.Add(400);
            Thread.Sleep(100);
            Console.WriteLine("Work Complete");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        return lst.Count;
    }
}


The issue can be resolved by adding “lock” before changing static field

public class MyClass
{
    public static List<int> lst = new List<int>();

    //DoWork with no lock will cause the application to fail
    public int DoWork()
    {
        try
        {
            lock (lst)
            { //setting lock will ensure thread safety
                Console.WriteLine("Work started");
                Thread.Sleep(300);
                lst.Add(100);
                Thread.Sleep(300);
                lst.Add(200);
                Thread.Sleep(100);
                lst.Add(300);
                Thread.Sleep(600);
                lst.Add(400);
                Thread.Sleep(100);
                Console.WriteLine("Work Complete");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        return lst.Count;
    }
}

Here is the complete code.


C#’s lock statement is in fact a syntactic shortcut for a call to the methods Monitor.Enter and Monitor.Exit, with a try/finally block. Here is the same example using Monitor



A Mutex is like a C# lock, but it can work across multiple processes. In other words, Mutex can be computer-wide as well as application-wide.

The lock construct is faster and more convenient than Mutex. Mutex has a niche in that its lock can span applications in different processes on the computer.

No comments: