且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何处理队列入队&在C#.NET中的不同线程中同时使进程出队

更新时间:2023-02-16 15:55:31

如果您查看System.Collections.Generic.Queue的MSDN描述(http://msdn.microsoft.com/en-us/library/7977ey2c.aspx [
If you look at MSDN description of System.Collections.Generic.Queue (http://msdn.microsoft.com/en-us/library/7977ey2c.aspx[^]) you will see that only read-only access to the instance of the queue is thread-safe, and only if enumeration is not used.

That said, you need to inter-lock the calls to Enqueue and Dequeue of the same instance accessed by different threads. This is a simple case of inter-locking where you should use lock statement.

For example, you can create a thread-safe wrapper around this type:
class Queue<ELEMENT> {
    internal void Enqueue(ELEMENT element) {
        lock(Implementation)
            Implementation.Enqueue(element);
    }
    internal ELEMENT Dequeue() {
        lock (Implementation)
            return Implementation.Dequeue();
    }
    //...
    System.Collections.Generic.Queue<ELEMENT> Implementation =
        new System.Collections.Generic.Queue<ELEMENT>();
    //...
}



重要提示:仅当您从未从包装类中公开实例Implementation时,才可以使用该实例.如果您需要以任何方式(甚至是只读)公开它,则应使用某个对象的一些私有实例(我将其称为SyncObject)用作lock的参数:



Important: you can use the instance Implementation only as soon as you never expose it from the wrapper class. Should you need to expose it in any way (even read-only), you should use some private instance of some object (I''ll call it SyncObject) to be used as the parameter of lock:

class Queue<ELEMENT> {
    internal void Enqueue(ELEMENT element) {
        lock(SyncObject)
            Implementation.Enqueue(element);
    }
    internal ELEMENT Dequeue() {
        lock (SyncObject)
            return Implementation.Dequeue();
    }
    //...
    System.Collections.Generic.Queue<ELEMENT> Implementation =
        new System.Collections.Generic.Queue<ELEMENT>();
    object SyncObject = new object();
    //...
}



—SA



—SA


我知道该问题未用.NET 4标记.

但是,如果您使用.NET 4,请签出 ConcurrentQueue [ ^ ]中. com/en-us/library/system.collections.concurrent.aspx> System.Collections.Concurrent [
I know that the question is not tagged with .NET 4.

But if you use .NET 4, then check out ConcurrentQueue[^] in System.Collections.Concurrent[^].