views:

399

answers:

4

Hello,

I am not too sure, so i thought i'd ask. Would removing and adding items to a System.Collections.Generic.List<> object be non-thread safe?

My situation:

When a connection is received, it is added to the list, but also at the same time, there's a worker that's removing dead connections and such.

Is there a problem? Will a lock do? I also want to know if i'm allowed to use a lock on the list object with it's Foreach<> method.

+2  A: 

List<T> is not thread-safe, so yes, you will need to control access to the list with a lock. If you have multiple threads accessing the List make sure you have them all respect the lock or you will have issues. The best way to do this would to be to subclass the List so that the locking happens automatically, else you will more than likely end up forgetting eventually.

Donnie
That's not the best way. It's not just because of List's implementation - also it's interface is not designed to be used by multiple threads. If you want a thread-safe way of doing this, you need a completely different interface too. The List should be an internal implementation detail, well hidden from users. http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx
Mark Byers
+9  A: 

Yes, adding and removing items from a List<> is not thread safe, so you need to synchronise the access, for example using lock.

Mind that the lock keyword in no ways locks the object that you use as identifier, it only prevents two threads to enter the same code block at the same time. You will need locks around all code that accesses the list, using the same object as identifier.

Guffa
+1 Nice explanation.
Andrew Hare
What about removing such in `List.Foreach<>`, does it still require a lock?
AJ Ravindiran
@AJ: Yes, you need a lock around *all* accesses to the list. If you are looping through the list and another thread removes an item, you will get an exception (or a crash in some circumstances).
Guffa
This answer pretty much covers the case of "yes, you need to lock over EVERYTHING that accesses the list". Your best bet is to provide a wrapper to the list, and lock over each method in the wrapper.
David_001
+1  A: 

Actually, sometimes List<> is thread-safe, and sometimes not, according to Microsoft:

Public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

but that page goes on to say:

Enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with one or more write accesses, the only way to ensure thread safety is to lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

DOK
No, a List is never thread safe. That's just a standard text used for all regular classes. As the List class doesn't have any static members at all, there are no thread safe members.
Guffa
I agree that he should definitely use a lock. Thanks for the clarification.
DOK
A: 

Definitely using lock for particular code makes it thread safe, but I do not agree with it for current scenario.

You can implement method Synchronized to make collection thread safe. This link explains why and how to do that.

Another purely programmatic approach is mentioned in this link, though I never tested it firsthand but it should work.

btw, one of the bigger concern is that, are you trying to maintain something like connection pool on you own? if yes then why?

BigBoss