Pratikgcet
Pratikgcet

Reputation: 31

Adding and removing items in a list at the same time in C#-Locks in Threads

I am sure this question would have been asked a lot of times, but I want to be clear of this concept.

Recently I came across a bug when two threads were accessing the same list in two different functions. In what scenarios can that cause problems if I don't have the proper locking? Even though I have a lock in the second function and the two threads are not related, they are manipulating the same list. One is adding and one is swapping with an empty list. Under what circumstances will it catch an exception? Please help.

PseudoCode:

List<SomeClass> list=new List<SomeClass>();

  object mutex=new object();

Thread 1 accesses this function and modifies the list:

public void Manipulate()
{

  //some operation
  list.add(new SomeClass());

}

Thread 2 access this function and clears the list:

public void SwapList()
{
   List<SomeClass> cls=new List<SomeClass>();
   try
   {
     while(Thread2.isAlive)
     {
       //some operation
       if(list.Count()>0)
       {
         lock(mutex)
         {
           swap(ref list,ref cls)
         }
       }
     }
  }
  catch(exception ex)
  {
  }
}
public void swap(List<SomeClass> a, List<SomeClass> b)
{
  List<SomeClass> temp=a;
  a=b;
  b=temp;
}

Upvotes: 3

Views: 3421

Answers (2)

Yosi Dahari
Yosi Dahari

Reputation: 7009

The locking should start as soon as you use the list:

lock(mutex)
{
  if(list.Count()>0)    
  {
     swap(ref list,ref cls)
   }
}

And it only helps if all those who wants to use it lock it (where is thread 1 locking?)

Edit:

Locking in thread 1 must be done in order for you to avoid race.

public void Manipulate()
{
  lock(mutex)
  {
    //some operation
    list.add(new SomeClass());
  }
}

I think reading about Thread-Safe Collections may help you - you can mostly avoid handle locking yourself in such cases.

About catching exceptions - in this specific case I can see no exception thrown from a case of concurrency. If you had a remove method, and you would try to swap specific items in your list it might have happened.

But there might be several other exceptions that might be happen, so I wouldn't put a block that catch any exception, but only those I can handle (swallowing exceptions is bad practice.)

Upvotes: 2

svick
svick

Reputation: 244998

In what scenarios can that cause problems if I don't have the proper locking?

Whenever you have at least two threads accessing the data at the same time and at least one of them is writing.

Because of that, you should lock whenever you have some data that can be accessed from multiple threads. And you need to lock every access to that data.

As an alternative, you could use thread-safe data structures (like collections in System.Collections.Concurrent). If you do that, you don't have to worry about locking yourself, because the structures already do it correctly (and efficiently).

Upvotes: 5

Related Questions