Why is it a bad practice to use lock as in the following code, I'm assuming this is a bad practice based on the answers in this SO question here
private void DoSomethingUseLess()
{
List<IProduct> otherProductList = new List<IProduct>();
Parallel.ForEach(myOriginalProductList, product =>
{
//Some code here removed for brevity
//Some more code here :)
lock (otherProductList)
{
otherProductList.Add((IProduct)product.Clone());
}
});
}
The answers over there mentions that it is bad practice , but they don't say why
Note: Please ignore the usefulness of the code, this is just for example purpose and i know it is not at all useful
From the C# language reference here:
In general, avoid locking on a public type, or instances beyond your code's control. The common constructs
lock (this)
,lock (typeof (MyType))
, andlock ("myLock")
violate this guideline:
lock (this)
is a problem if the instance can be accessed publicly.
lock (typeof (MyType))
is a problem ifMyType
is publicly accessible.
lock("myLock")
is a problem because any other code in the process using the same string, will share the same lock.Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.
In your case, I would read the above guidance as suggesting that locking on the collection you will be modifying is bad practise. For example, if you wrote this code:
lock (otherProductList)
{
otherProductList = new List<IProduct>();
}
...then your lock will be worthless. For these reasons it's recommended to use a dedicated object
variable for locking.
Note that this doesn't mean your application will break if you use the code you posted. "Best practices" are usually defined to provide easily-repeated patterns that are more technically resilient. That is, if you follow best practice and have a dedicated "lock object," you are highly unlikely to ever write broken lock
-based code; if you don't follow best practice then, maybe one time in a hundred, you'll get bitten by an easily-avoided problem.
Additionally (and more generally), code written using best practices is typically more easily modified, because you can be less wary of unexpected side-effects.