When to use the lock thread in C#? When to use the lock thread in C#? multithreading multithreading

When to use the lock thread in C#?


You ever sit in your car or on the bus at a red light when there's no cross traffic? Big waste of time, right? A lock is like a perfect traffic light. It is always green except when there is traffic in the intersection.

Your question is "I spend too much time in traffic waiting at red lights. Should I just run the red light? Or even better, should I remove the lights entirely and just let everyone drive through the intersection at highway speeds without any intersection controls?"

If you're having a performance problem with locks then removing locks is the last thing you should do. You are waiting at that red light precisely because there is cross traffic in the intersection. Locks are extraordinarily fast if they are not contended.

You can't eliminate the light without eliminating the cross traffic first. The best solution is therefore to eliminate the cross traffic. If the lock is never contended then you'll never wait at it. Figure out why the cross traffic is spending so much time in the intersection; don't remove the light and hope there are no collisions. There will be.

If you can't do that, then adding more finely-grained locks sometimes helps. That is, maybe you have every road in town converging on the same intersection. Maybe you can split that up into two intersections, so that code can be moving through two different intersections at the same time.

Note that making the cars faster (getting a faster processor) or making the roads shorter (eliminating code path length) often makes the problem worse in multithreaded scenarios. Just as it does in real life; if the problem is gridlock then buying faster cars and driving them on shorter roads gets them to the traffic jam faster, but not out of it faster.


Is the lock needed when I write to the public accessed variables (C# lists) only or even when I read from them ?

Yes (even when you read).

Is the lock needed only in the asyncronous threads created by the socket handler or in other places too ?

Yes. Wherever code accesses a section of code which is shared, always lock.


This sounds like you may not be locking individual objects, but locking one thing for all lock situations.

If so put in smart discrete locks by creating individual unique objects which relate and lock only certain sections at a time, which don't interfere with other threads in other sections.

Here is an example:

// This class simulates the use of two different thread safe resources and how to lock them// for thread safety but not block other threads getting different resources.public class SmartLocking{    private string StrResource1 { get; set; }    private string StrResource2 { get; set; }    private object _Lock1 = new object();    private object _Lock2 = new object();    public void DoWorkOn1( string change )    {        lock (_Lock1)        {            _Resource1 = change;        }    }    public void DoWorkOn2( string change2 )    {        lock (_Lock2)        {            _Resource2 = change2;        }    }}


Always use a lock when you access members (either read or write). If you are iterating over a collection, and from another thread you're removing items, things can go wrong quickly.

A suggestion is when you want to iterate a collection, copy all the items to a new collection and then iterate the copy. I.e.

var newcollection; // Initialize etc.lock(mycollection){  // Copy from mycollection to newcollection}foreach(var item in newcollection){  // Do stuff}

Likewise, only use the lock the moment you are actually writing to the list.