How to add elements in Queue (Queue) continuously?

Asked

Viewed 237 times

0

Below I have a code that he needs to do the following: Create a thread, then start it. When starting the thread, according to the time (random time) the program adds a value in the queue, after being added in the queue, it needs to show how many elements there are in the queue. However, when executed, the program does not exceed 1 element in the queue (even though it has already passed the time to add another element). How to solve this problem?

namespace MultiThreads
{
    public partial class Form1 : Form
    {
        private Queue<int> FilaClientes = new Queue<int>();
        List<Thread> lt = new List<Thread>();

        public Form1()
        {
            InitializeComponent();
        }

        private static void UpdateFila(TextBox tx, Queue<int> Fila)
        {
            tx.Text = Fila.Count.ToString();
        }

        private void AdicionaClientesFila(TextBox tx)
        {
            Stack<int> TempoParaFila = new Stack<int>();
            Random TempoVaria = new Random((int)DateTime.Now.Ticks & 
                                            0x0000FFFF);
            TempoParaFila.Push(TempoVaria.Next(1, 1001));
            int Aux = TempoParaFila.Pop();
            Thread.Sleep(Aux);

            //acima é descrito o valor em tempo para 
            //chegar alguém na fila

            Random ItensFila = new Random((int)DateTime.Now.Ticks & 
                                            0x0000FFFF);
            Stack<int> NovoCliente = new Stack<int>();
            NovoCliente.Push(ItensFila.Next(1, 1001));
            FilaClientes.Enqueue(NovoCliente.Pop());
            //Acima é adicionado a quantidade de itens do cliente

            if (txtboxTamanhoFila.InvokeRequired)
            {
                MethodInvoker m = new MethodInvoker(() => UpdateFila(tx, 
                                                     FilaClientes));
                tx.Invoke(m);
            }
            else
            {
                UpdateFila(tx, FilaClientes);
            }

            Application.DoEvents();
        }

        private void btnInicia_Click(object sender, EventArgs e)
        {
            foreach(Thread t in lt)
            {
                t.Start();
                Thread.Sleep(500);
            }
        }

        private void btnCriar_Click(object sender, EventArgs e)
        {
            lt.Add(new Thread(() => 
                        AdicionaClientesFila(txtboxTamanhoFila)));
        }
    }
}

1 answer

2


Quick fix use a static concurrent queue.

private static ConcurrentQueue<int> FilaClientes = new Queue<int>();

Considerations

  1. Avoid using new Thread(). When creating a new thread, it will be created in a processor core and the load will not be distributed. That is, depending on the processing processes in this core will be affected and the overall performance will fall. Whenever possible uses Tasks (TPL https://docs.microsoft.com/pt-br/dotnet/standard/parallel-programming/task-based-asynchronous-programming). The . net people solved it a lot well.
  2. Instead of always firing a new thread (or task) in the click, you can in the creation of the form start a task that will be inside a looping while looking at the queue. When you have an item in the queue it processes.
  3. I did not understand the use of the stack in the Add Clientsfila method. The instruction is Sleep(Randomtime), Enqueue(Randomvalue).

        var time = new Random().Next(minValue: 200, maxValue: 5000);
        Task.Delay(millisecondsDelay: time);
    
        var item = new Random().Next(minValue: 100, maxValue: 10000);
        FilaClientes.Enqueue(item: item);
    
  4. I suggest reading the guid style of . net (local variables start with lowercase letter. Use var for local variables). https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/

If in doubt, further detail your goal.

  • The goal is to simulate the queue of a store, but with your answer I managed to find a solution

Browser other questions tagged

You are not signed in. Login or sign up in order to post.