Dequeueing objects from a ConcurrentQueue in C#

后端 未结 3 839
野趣味
野趣味 2020-12-31 15:00

Hey, I\'m trying to implement a ConcurrentQueue in C# for an asynchronous server. Items are being queued as soon as a complete message is received. To dequeue messages, I\

3条回答
  •  萌比男神i
    2020-12-31 15:30

    You could use a static locking object for the threads to wait on and then pulse it when something is ready to be processed.

    static readonly object queueLock = new object();
    
    // Threads that enqueue an object
    void QueueMessage() {
      lock (queueLock) {
        queue.Enqueue(obj);
        Monitor.Pulse(queueLock);
      }
    }
    // Thread dequeuer
    private void startParsingMessages() {
      QueueContainer dequeued = null;
      Console.WriteLine("Trying");
      while (true) {
        lock(queueLock) {
          if (!queue.TryDequeue(out dequeued)) {
            Console.WriteLine("No object to dequeue, waiting...");
            // Threads will wait here and only one will be released when .Pulse()d
            Monitor.Wait(queueLock);
            dequeued = queue.Dequeue();
          }
          if (dequeued != null) {
            Console.WriteLine("processing queue");
            ProcessMessage(dequeued.socket, dequeued.message);
          }
        }
      }
    }
    

    Keep in mind that this can get quite complicated with the more branches you have, but the gist of it is, you lock on a common object and call Monitor.Wait to wait on an object to be Pulsed. When this happens only one thread that was waiting on it will be released. If you enqueue a lot of objects and want them all to go, you can call Monitor.PulseAll which will release all threads that were waiting on the object.

提交回复
热议问题