Click here to Skip to main content
15,885,767 members
Home / Discussions / C#
   

C#

 
GeneralRe: C# features Pin
PIEBALDconsult26-May-23 11:42
mvePIEBALDconsult26-May-23 11:42 
AnswerRe: C# features Pin
Richard MacCutchan26-May-23 1:04
mveRichard MacCutchan26-May-23 1:04 
GeneralRe: C# features Pin
Calin Negru26-May-23 21:37
Calin Negru26-May-23 21:37 
AnswerRe: C# features Pin
BillWoodruff26-May-23 19:42
professionalBillWoodruff26-May-23 19:42 
GeneralRe: C# features Pin
Calin Negru29-May-23 6:05
Calin Negru29-May-23 6:05 
QuestionGoogle API Authentication in a WPF App Pin
Kevin Marois22-May-23 14:04
professionalKevin Marois22-May-23 14:04 
AnswerRe: Google API Authentication in a WPF App Pin
Dave Kreskowiak22-May-23 18:54
mveDave Kreskowiak22-May-23 18:54 
QuestionConcurrentList<T> Pin
Richard Andrew x6421-May-23 8:40
professionalRichard Andrew x6421-May-23 8:40 
Microsoft provides a group of thread-safe collections, but conspicuously does not provide a thread-safe List<T>. What is the reason? Is it not feasible to make a thread-safe version of a List<T>?

I need an ordered, sortable collection that is thread-safe.

I might get flamed, but I'm about to copy and paste some code I found on the internet. On stack exchange, I found the following post:

https://codereview.stackexchange.com/questions/62033/creating-a-thread-safe-list-using-a-lock-object[^]

To me, it looks like it would work and be thread-safe.

I'm wondering if some more experienced and respected members can tell me if this code looks like it might indeed be thread safe. The key bit about this code is that it uses callbacks to be able to keep the collection locked even while enumerating it or performing some other types of access.

I have reproduced the code below for convenience:

(If you consider this post inappropriate due to its length, please let me know, and I won't do it again.)

public class ConcurrentList<T> : IList<T>
{
    #region Fields

    private IList<T> _internalList;

    private readonly object lockObject = new object();

    #endregion

    #region ctor

    public ConcurrentList()
    {
        _internalList = new List<T>();
    }

    public ConcurrentList(int capacity)
    {
        _internalList = new List<T>(capacity);
    }

    public ConcurrentList(IEnumerable<T> list)
    {
        _internalList = list.ToList();
    }

    #endregion

    public T this[int index]
    {
        get
        {
            return LockInternalListAndGet(l => l[index]);
        }

        set
        {
            LockInternalListAndCommand(l => l[index] = value);
        }
    }

    public int Count
    {
        get
        {
            return LockInternalListAndQuery(l => l.Count());
        }
    }

    public bool IsReadOnly => false;

    public void Add(T item)
    {
        LockInternalListAndCommand(l => l.Add(item));
    }

    public void Clear()
    {
        LockInternalListAndCommand(l => l.Clear());
    }

    public bool Contains(T item)
    {
        return LockInternalListAndQuery(l => l.Contains(item));
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        LockInternalListAndCommand(l => l.CopyTo(array, arrayIndex));
    }

    public IEnumerator<T> GetEnumerator()
    {
        return LockInternalListAndQuery(l => l.GetEnumerator());
    }

    public int IndexOf(T item)
    {
        return LockInternalListAndQuery(l => l.IndexOf(item));
    }

    public void Insert(int index, T item)
    {
        LockInternalListAndCommand(l => l.Insert(index, item));
    }

    public bool Remove(T item)
    {
        return LockInternalListAndQuery(l => l.Remove(item));
    }

    public void RemoveAt(int index)
    {
        LockInternalListAndCommand(l => l.RemoveAt(index));
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return LockInternalListAndQuery(l => l.GetEnumerator());

    }

    #region Utilities

    protected virtual  void LockInternalListAndCommand(Action<IList<T>> action)
    {
        lock (lockObject)
        {
            action(_internalList);
        }
    }

    protected virtual T LockInternalListAndGet(Func<IList<T>, T> func)
    {
        lock (lockObject)
        {
            return func(_internalList);
        }
    }

    protected virtual TObject LockInternalListAndQuery<TObject>(Func<IList<T>, TObject> query)
    {
        lock (lockObject)
        {
            return query(_internalList);
        }
    }

    #endregion
}




The difficult we do right away...
...the impossible takes slightly longer.


modified 21-May-23 16:33pm.

AnswerRe: ConcurrentList<T> Pin
Gerry Schmitz21-May-23 8:50
mveGerry Schmitz21-May-23 8:50 
GeneralRe: ConcurrentList<T> Pin
Richard Andrew x6421-May-23 10:32
professionalRichard Andrew x6421-May-23 10:32 
GeneralRe: ConcurrentList<T> Pin
Gerry Schmitz22-May-23 12:01
mveGerry Schmitz22-May-23 12:01 
GeneralRe: ConcurrentList<T> Pin
BillWoodruff22-May-23 11:38
professionalBillWoodruff22-May-23 11:38 
GeneralRe: ConcurrentList<T> Pin
Gerry Schmitz22-May-23 12:06
mveGerry Schmitz22-May-23 12:06 
AnswerRe: ConcurrentList<T> Pin
Richard Deeming21-May-23 21:05
mveRichard Deeming21-May-23 21:05 
GeneralRe: ConcurrentList<T> Pin
Richard Andrew x6422-May-23 6:28
professionalRichard Andrew x6422-May-23 6:28 
GeneralRe: ConcurrentList<T> Pin
Richard Deeming22-May-23 20:40
mveRichard Deeming22-May-23 20:40 
AnswerRe: ConcurrentList<T> Pin
jschell22-May-23 7:11
jschell22-May-23 7:11 
AnswerRe: ConcurrentList<T> Pin
lmoelleb26-May-23 2:55
lmoelleb26-May-23 2:55 
GeneralRe: ConcurrentList<T> Pin
Richard Andrew x6431-May-23 13:22
professionalRichard Andrew x6431-May-23 13:22 
QuestionOpen Browser, Wait for Callback Pin
Kevin Marois19-May-23 6:43
professionalKevin Marois19-May-23 6:43 
AnswerRe: Open Browser, Wait for Callback Pin
Dave Kreskowiak19-May-23 7:08
mveDave Kreskowiak19-May-23 7:08 
GeneralRe: Open Browser, Wait for Callback Pin
Kevin Marois19-May-23 8:12
professionalKevin Marois19-May-23 8:12 
GeneralRe: Open Browser, Wait for Callback Pin
Gerry Schmitz19-May-23 8:46
mveGerry Schmitz19-May-23 8:46 
GeneralRe: Open Browser, Wait for Callback Pin
Dave Kreskowiak19-May-23 10:51
mveDave Kreskowiak19-May-23 10:51 
GeneralRe: Open Browser, Wait for Callback Pin
Gerry Schmitz20-May-23 4:00
mveGerry Schmitz20-May-23 4:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.