This tip shows how to simplify your lock usage in C#.
I saw a Tweet yesterday complaining about the need to create an empty object to use as the parameter in a lock
statement. They wanted this to be simplified.
It struck me that constant strings with the same content all reference the same object as the strings are interned. Thus you could just lock on a constant string without having to create an object. Thus you could do something like the code below. Of course, typos could cause you no end of pain.
Just to be clear, this is not intended to be a 'best practice'. Magic strings and the potential of multiple code sections inadvertently sharing the same string (lock
object) far outweigh any benefits this pattern might add. However, it was an interesting observation of one feature of the C# compiler/runtime.
Console.WriteLine($"The strings are the same object {ReferenceEquals("A String", "A String")}");
var taskList = new List<Task>();
for (var i = 0; i < 10; i++)
{
taskList.Add(RunTask1(i));
taskList.Add(RunTask2(i));
}
Task.WaitAll(taskList.ToArray());
Console.WriteLine("Done");
async Task RunTask1(int i)
{
await Task.Delay(1);
lock ("A String")
{
Console.WriteLine($"Entering task1-{i} lock");
Thread.Sleep(500);
Console.WriteLine($"Exiting task1-{i} lock");
}
}
async Task RunTask2(int i)
{
await Task.Delay(200);
lock ("A String")
{
Console.WriteLine($"Entering task2-{i} lock");
Thread.Sleep(300);
Console.WriteLine($"Exiting task2-{i} lock");
}
}
The strings are the same object True
Entering task1-0 lock
Exiting task1-0 lock
Entering task1-1 lock
Exiting task1-1 lock
Entering task1-3 lock
Exiting task1-3 lock
Entering task1-2 lock
Exiting task1-2 lock
Entering task1-5 lock
Exiting task1-5 lock
Entering task1-9 lock
Exiting task1-9 lock
Entering task2-7 lock
Exiting task2-7 lock
Entering task2-9 lock
Exiting task2-9 lock
Entering task2-6 lock
Exiting task2-6 lock
Entering task2-5 lock
Exiting task2-5 lock
Entering task2-3 lock
Exiting task2-3 lock
Entering task1-4 lock
Exiting task1-4 lock
Entering task1-8 lock
Exiting task1-8 lock
Entering task1-7 lock
Exiting task1-7 lock
Entering task1-6 lock
Exiting task1-6 lock
Entering task2-8 lock
Exiting task2-8 lock
Entering task2-4 lock
Exiting task2-4 lock
Entering task2-2 lock
Exiting task2-2 lock
Entering task2-1 lock
Exiting task2-1 lock
Entering task2-0 lock
Exiting task2-0 lock
Done
History
- 10th December, 2022: Initial version
As Senior Architect, Matthew is responsible for the Architecture, Design, and Coding of the CodeProject software as well as Manager of the Infrastructure that runs the web site.
Matthew works on improving the performance and experience of the Code Project site for users, clients, and administrators.
Matthew has more years of software development, QA and architecture experience under his belt than he likes to admit. He graduated from the University of Waterloo with a B.Sc. in Electrical Engineering. He started out developing micro-processor based hardware and software including compilers and operating systems.
His current focus is on .NET web development including jQuery, Webforms, MVC, AJAX, and patterns and practices for creating better websites.
He is the author of the
Munq IOC, the fastest ASP.NET focused IOC Container.
His non-programming passions include golf, pool, curling, reading and building stuff for the house.