Synchronize list in C#

Thread synchronization is defined as a mechanism which ensures that two or more concurrent processes or threads do not simultaneously execute some particular program segment known as mutual exclusion. When one thread starts executing the critical section (serialized segment of the program) the other thread should wait until the first thread finishes. If proper synchronization techniques[1] are not applied, it may cause a race condition where, the values of variables may be unpredictable and vary depending on the timings of context switches of the processes or threads.(Reference:Wikipedia)

You could use below code or download it in C# for synchronize List:

public class SyncList<T>
{
  private List<T> mLst = new List<T>();
  private ReaderWriterLockSlim mLock = new ReaderWriterLockSlim();

//*********************************
//
//*********************************
public void Add(T newItem)
{
  mLock.EnterWriteLock();
  try
  {
    mLst.Add(newItem);
  }
  finally
  {
    mLock.ExitWriteLock();
  }
}
//*********************************
//
//*********************************
public T TakeFirst()
{
  mLock.EnterReadLock();
  try
  {
    T tmp = mLst[0];
    mLst.RemoveAt(0);

    return tmp;
  }
  finally
  {
    mLock.ExitReadLock();
  }
}
//*********************************
//
//*********************************
public T TakeAt(int index)
{
  mLock.EnterReadLock();
  try
  {
    T tmp = mLst[index];
    mLst.RemoveAt(index);

    return tmp;
  }
  finally
  {
    mLock.ExitReadLock();
  }
}
//*********************************
//
//*********************************
public T GetAt(int index)
{
  mLock.EnterReadLock();
  try
  {
    return mLst[index];
  }
  finally
  {
    mLock.ExitReadLock();
  }
}
//*********************************
//
//*********************************
public T this[int index]
{
  get
  {
    mLock.EnterReadLock();
    try
    {
      return mLst[index];
    }
    finally
    {
      mLock.ExitReadLock();
    }
  }
  set
  {
    mLock.EnterWriteLock();
    try
    {
      mLst[index] = value;
    }
    finally
    {
      mLock.ExitWriteLock();
    }
  }
}
//*********************************
//
//*********************************
public void SetAt(int index,T value)
{
  mLock.EnterWriteLock();
  try
  {
    mLst[index] = value;
  }
  finally
  {
    mLock.ExitWriteLock();
  }
}
//*********************************
//
//*********************************
public void RemoveAt(int index)
{
  mLock.EnterWriteLock();
  try
  {
    mLst.RemoveAt(index);
  }
  finally
  {
    mLock.ExitWriteLock();
  }
}
//*********************************
//
//*********************************
public void Remove(T obj)
{
  mLock.EnterWriteLock();
  try
  {
    int index = mLst.IndexOf(obj);
    if( index != -1 )
      mLst.RemoveAt(index);
  }
  finally
  {
    mLock.ExitWriteLock();
  }
}
//*********************************
//
//*********************************
public void Clear()
{
  mLock.EnterWriteLock();
  try
  {
    mLst.Clear();
  }
  finally
  {
    mLock.ExitWriteLock();
  }
}
//*********************************
//
//*********************************
public int IndexOf(T itemToSearch)
{
  mLock.EnterReadLock();
  try
  {
    return mLst.IndexOf(itemToSearch);
  }
  finally
  {
    mLock.ExitReadLock();
  }
}
//*********************************
//
//*********************************
public int Count
{
  get
  {
    mLock.EnterReadLock();
    try
    {
      return mLst.Count;
    }
    finally
    {
      mLock.ExitReadLock();
    }
  }
}
}