开发者

Queue Syncronization and operations in C#

开发者 https://www.devze.com 2023-03-21 03:02 出处:网络
If a Queue is syncronized: var _item = Queue.Synchronized(new Queue()); can I call methods like Enqueue and Dequeue on it without using lock statements?

If a Queue is syncronized:

var _item = Queue.Synchronized(new Queue());

can I call methods like Enqueue and Dequeue on it without using lock statements?

My current code is:

lock (_item.SyncRoot)
{
    _item.Enqueue(开发者_如何学Goobj);
}

Can I thread-safely use:

_item.Enqueue(obj);
var item = _item.Dequeue();


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消