While they have been oft repeated, the following C# locking rules deserve at least one more go around:
- Never lock a value type (e.g.
ints andstructs). -
Value types will be boxed into objects, and multiple boxings will not result in the same object, so mutual exclusion will not be assured.
- Never lock
this. -
It opens up the possibility for deadlock, as in the following code:
class A { public void f() { lock (this) { // Do work } } } class B { public void g() { A a = new A(); lock (a) { a.f(); // Deadlock! } } } - Never lock
stringinstances. -
Because strings are interned, two strings with the same contents are the same object and thus correspond to one lock — almost certainly not what you intended. Furthermore, interned strings are shared across application domains.
- Never lock
Typeobjects. -
See the June 5, 2003 Dr. GUI article for the reason why.
- Be careful about holding a lock while calling code you don’t control.
-
This includes virtual and abstract functions.
- Establish and follow a locking order.
-
Multiple threads grabbing locks in differing orders is a classic recipie for deadlock.
If your class needs a lock, consider creating a private member object to act as one. For example:
class A
{
private object m_lock = new object();
public void f()
{
lock (m_lock)
{
// Do work
}
}
}
Hat tip: Threading Tips.
Recent Comments