I have a method similar to:
public static void DoSomething (string param1, string param2, SomeObject o)
{
//.....
lock(o)
{
o.Things.Add(param1);
o.Update();
// etc....
}
}
A few points:
- Is locking in this way bad practice?
- Should I lock on a
private static objectinstead? - If so, why?
To minimize side effects, the object being locked on should not be the object being manipulated but rather a separate object designated for locking.
Depending on your requirements, there are a few options for handling this issue:
Variant A: Private locking object
Choose this if you just want to ensure that
DoSomethingdoes not conflict with a parallel instance ofDoSomething.Variant B: Pass locking object as a parameter
Choose this if access to
omust be thread-safe even outside ofDoSomething, i.e., if the possibility exists that someone else writes a methodDoSomethingElsewhich runs in parallel toDoSomethingand which must not interfere with thelockblock inDoSomething:Variant C: Create SyncRoot property
If you have control over the implementation of
SomeObject, it might be convenient to provide the locking object as a property. That way, you can implement Variant B without having to pass around a second parameter:Then, you just use
lock(o.SyncRoot)inDoSomething. That’s the pattern some of the BCL classes use, e.g., Array.SyncRoot, ICollection.SyncRoot.