score:4

Accepted answer

the call to enqueue and the call to dequeue are thread safe.
however, your sample code is not:
between the call to enqueue and the call to dequeue there could have been a thread switch. this means, that item might be another instance than obj or the call to dequeue throws an exception, because it now is empty.

to make your sample code thread safe, you still need to lock explicitly:

lock(_item.syncroot)
{
    _item.enqueue(obj);
    var item = _item.dequeue);
}

only now it is guaranteed, that item reference-equals obj in all circumstances.

score:2

from msdn

to guarantee the thread safety of the queue, all operations must be done through this wrapper only.

enumerating through a collection is intrinsically not a thread-safe procedure. even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. to guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.

just as john skeet's answer suggests here, you might be better or using locking since enumerating might cause an exception.

gregs answer also talks about what marc mentions with the count not being thread safe.

score:4

that is pretty much what synchronizedqueue does, but there is a problem... typically you need to check the .count and .dequeue() in one atomic unit - not check the .count (one unit) then .dequeue() (another unit) - you can't trust .count at all once the lock is surrendered, and .dequeue() will throw if another thread has stolen the work.

maybe try concurrentqueue<t> in 4.0 (with .trydequeue()), or use queue<t> and lock.


Related Query

More Query from same tag