Search code examples
c#multithreadingparallel-processingproducer-consumerblockingcollection

Queue and deque at the same time


I am working on a project that requires read a QR code, queue it, as it is queue another task dequeues the data and send it to machine via socket messaging. This is all done in C#.

My question is how would I keep queue while another task is dequeuing. I have the QR code working, I can queue and dequeue and the socket messaging portion working. But I don't know how to run the queue and dequeue at the same time.

I have looked into threading, specifically multi threading. I am more confused than before I started reading.

Any help will be greatly appreciated.

EDIT: So based on you comments and doing a little bit of research, I started writing a bit of code. No matter what I did, the thread only runs once. It is supposed to keep running.

public partial class Form1 : Form
{
    private BlockingCollection<string> _queue = new BlockingCollection<string>(30);
    //private string item = "A";
    //private int count = 0;
    private Thread _th1;

    public Form1()
    {
        InitializeComponent();
        _th1 = new Thread(thread_example);
        _th1.Start();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    }

    private void thread_example()
    {
        if (_queue.Count > 0)
        {
            _queue.Take();
            Console.WriteLine("Removed 1 Item from queue!");
        }
        else
        {
            Console.WriteLine("Queue Empty!");
        }
        Thread.Sleep(500);
    }

    private void btnProduce_Click(object sender, EventArgs e)
    {
        _queue.Add("test_string");
        Console.WriteLine("Added 1 item to the queue");
    }
}

Solution

  • I would highly recommend using BlockingCollection. The problem you have is called a Producer-Consumer problem

    BlockingCollection provides an implementation that handles the Producer-Consumer problem.

    Specifically, you have to also think about: What happens when the dequeuing thread gets slow and can't keep up with the scanning thread, say due to network slowness at that time?

    The BlockingCollection will block the queuing thread to slow the whole process in sync, based on the BlockingCollection Capacity specified while constructing.

    Also, you can get either FIFO or LIFO behavior, by using ConcurrentQueue or ConcurrentBag as the underlying storage. BlockingCollection just provides the "bounded-ness" properties on top of the underlying synchronized collections.