C # multithreaded list operations

If I have something like this (pseudocode):

class A
{
    List<SomeClass> list;

    private void clearList()
    {
        list = new List<SomeClass>();
    }

    private void addElement()
    {
        list.Add(new SomeClass(...));
    }
}

Is it possible that I came across multithreading issues (or any unexpected behavior) when both functions are executed in parallel?

A usage example is a list of errors that could be cleared at any time (simply by assigning a new empty list).

EDIT: My Assumptions

  • only one thread adds items
  • forgotten items are in order (that is, a race condition between cleaning and adding a new item) if the cleaning operation completed successfully without problems.
  • .NET 2.0
+5
source share
6 answers

There are two possibilities:

  • , . ? , AddElement ClearList , : , ().
  • List<T> , , AddElement , .

, , . / .

EDIT: , , , , :

  • ( !), List<T>, . , .NET 2.0 ( ECMA) , , .
  • , "" list . , -

" " , - . , , , , :

class A
{
    private List<SomeClass> list;
    private readonly object listLock = new object();

    private void ClearList()
    {
        lock (listLock)
        {
            list = new List<SomeClass>();
        }
    }

    private void AddElement()
    {
        lock (listLock)
        {
            list.Add(new SomeClass(...));
        }
    }

    private List<SomeClass> CopyList()
    {
        lock (listLock)
        {
            return new List<SomeClass>(list);
        }
    }

}
+10

- . , , .

, , addElement.

- , .

. - :

class A
{
    static object myLock = new object()
    List<SomeClass> list;

    private void clearList()
    {
        lock(myLock)
        {
          list = new List<SomeClass>();
        }

    }

    private void addElement()
    {
        lock(myLock)
        {
          list.Add(new SomeClass(...));
        }
    }
}
+2

.NET( 3.5) ( ). , IList ReaderWriterLockSlim . , Add :

    public void Add(T item)
    {
        _readerWriterLockSlim.EnterWriteLock();
        try { _actualList.Add(item); }
        finally { _readerWriterLockSlim.ExitWriteLock(); }
    }

concurrency . , GetEnumerator, IList; . ; :

    public IEnumerator<T> GetEnumerator()
    {
        List<T> localList;

        _lock.EnterReadLock();
        try { localList= new List<T>(_actualList); }
        finally { _lock.ExitReadLock(); }

        foreach (T item in localList) yield return item;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<T>)this).GetEnumerator();
    }

. - ( ) , ! , , , .. , !

+2

, , .

, , .

, , , , ? , , .

.Net 4 :)

: System.Collections.Concurrent, .Net 4. : System.Collections.Concurrent.ConcurrentBag<T> :)

, , .

+1

, . . .NET Framework ( 3.5 ) . , , .

"" .Net 4.0, .

+1

, - .

, , , .

, . , . , .

I think that as thin as it is, there is still a chance, especially in multiprocessor environments, that the process will receive a corrupted link because it was only partially updated when it accessed it.

0
source

All Articles