tags:

views:

45

answers:

3

Suppose I have two objects a and b.

I want to SyncLock on both objects.

Is this feasible? Can it be done by nested SyncLock statements? What are the dangers of such an operation?

Edit

Perhaps I should ask, how can one refactor to avoid deadlocks?

A: 

It's possible to do but you need to consider what happens if 2 threads running this code try to get both locks at the same time - eg if thread 1 has a lock on object 1 and thread 2 has a lock on object 2? Cue deadlock.

Someone better than I can give you some example code that should be safe :)

Basiclife
+3  A: 

Nested locks will work - however one of the dangers is that one needs to always lock the objects in the same order, else one could cause a deadlock.


EDIT: To answer the second question around trying force the correct order of locks:

A possible solution to avoid this might be to encapsulate the locking into a common lock method like this:

public void LockAndDoWork(Action action)
{
 lock(lockObject1)
 {
  lock(lockObject2)
  {
    action();
  }
 }
}

This could then be used like this:

Thread1: LockAndDoWork(() => {do some work....});
Thread2: LockAndDoWork(() => {do some other work...});

This can help avoid this potential issue - it's especially useful if one can limit visibility to those objects from client code

saret
While this is c#, you can do the same thing in VB.Net
saret
A: 

Perhaps I should ask, how can one refactor to avoid deadlocks?

Defining all sync locks in a strong order of priority and always taking the highest priority first.

This is hard: when one code block holding a lower priority lock could call into helper code that needs to take a higher priority lock significant refactoring will be needed.

Richard