How make custom Thread Safe Generic List return the whole list in C#?

和自甴很熟 提交于 2019-12-05 10:20:57

Agree with @jrista. There's a semantics issue you need to resolve, and why is it called Translate()? What is the intent?

A - current code - return a read-only wrapper of the internal list

return new ReadOnlyCollection<T>(list);

You still have threading issues if the original list is changed if another thread is iterating over the list. As long as you're aware of this, it isn't a huge issue.

B - a read-only copy.

return new List<T>(list).AsReadOnly();

This list has no threading issues because nothing modifies the new list. The only reference held is by the ReadOnlyCollection<T> wrapper.

C - a normal (writable) copy

return new List<T>(list);

Returns a new list, and the caller can do what they wish to their list without affecting the original list, and changes to the original list do not affect this list.


Does it matter if another consumer grabs a copy of the list and then modifies their copy? Do consumers need to see changes to the list? Do you just need a thread-safe enumerator?

public IEnumerator<T> ThreadSafeEnumerator()
{
    List<T> copy;
    lock(lockable)
        copy = new List<T>(list);

    foreach (var value in copy)
        yield return value;
}

In my experience you have to use your brain when it comes to thread-safety and not rely on solutions such as these. in short, it depends on what the receiver of the list is going to be doing with it.

The Translate() method looks correct. Using the lock you are preventing others from adding or otherwise modifying your list while you are in Translate/AddRange.

I think there might be a problem with your IsReadyOnly property though. You use a lock when reading/writing the property internally. But there also is a public getter which is not locked. It might happen that thread 1 calls MarkAsReadOnly while a second thread might still get false when looking at IsReadOnly. I'd use a normal property instead and either lock in the getter or use a volatile bool field.

You can use SynchronizedCollection.

http://msdn.microsoft.com/en-us/library/ms668265.aspx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!