Update data in a winform from a Database

0

I have a winforms application, which draws some controls inside a panel, obtaining some data from a database, and running in an endless while cycle with a time of 5 seconds between each query. the form is drawn correctly, and the data also matches those in the database. The problem is that the click that runs infinitely, does not refresh the data when the value in the database changes. If for example I stop the application, and restart it, the data is displayed correctly as they are in the database. here is my code of the form.

        private void button1_Click(object sender, EventArgs e)
    {
        while (1 == 1)
        {
            int iContador = 0;
            CA_DispensadorRepository dispensadorRepo = new CA_DispensadorRepository();
            List<CA_Dispensador> lstDispensador = dispensadorRepo.GetAll();
            if (lstDispensador != null && lstDispensador.Count > 0)
            {

                foreach (CA_Dispensador dispensador in lstDispensador)
                {
                    Application.DoEvents();

                    iContador++;
                    if (iContador <= 5)
                    {
                        GroupBox MiGroupBox = new System.Windows.Forms.GroupBox();
                        MiGroupBox.Name = dispensador.DirecionHexa.Trim().ToUpper();

                        Label AbiertoLabel = new System.Windows.Forms.Label();
                        if (dispensador.Abierto)
                        {
                            AbiertoLabel.Text = "Abierto SI";
                        }
                        else
                        {
                            AbiertoLabel.Text = "Abierto NO";
                        }
                        AbiertoLabel.Size = new System.Drawing.Size(80, 17);
                        AbiertoLabel.AutoSize = true;
                        AbiertoLabel.Location = new System.Drawing.Point(17, 20);
                        AbiertoLabel.Name = "Abierto";
                        AbiertoLabel.TabIndex = 0;

                        MiGroupBox.Controls.Add(AbiertoLabel);

                        int Columna = 12 * (iContador * 6);
                        MiGroupBox.Location = new Point(12, Columna);
                        MiGroupBox.SuspendLayout();
                        MiGroupBox.Size = new System.Drawing.Size(200, 71);
                        MiGroupBox.TabIndex = 0;
                        MiGroupBox.TabStop = false;

                        panel1.Controls.Add(MiGroupBox);
                        Application.DoEvents();

                    }
                    Application.DoEvents();

                }
            }
            Application.DoEvents();

            Thread.Sleep(5000);

        }

    }

Any idea why the application is "frozen" ?? Greetings and thanks for your time

    
asked by Luis Gabriel Fabres 31.10.2017 в 23:13
source

2 answers

0

What I see is that every one that enters the cycle creates a groupbox and within this the controls, this in each round, it is not that it does not refresh, but that you put one groupbox over another, so that this does not happen you must do one of 2 things, eliminate the groupbox with everything and controls and create them again or check if a control already exists, do not believe it, you only assign the value. And as they recommend, try using a timer instead of an infinite cycle.

Greetings

    
answered by 01.11.2017 в 02:08
0

According to the documentation of Thread.Sleep() :

  

Suspend the current thread for a specified time

For each iteration of the while , you are suspending the thread from the view of your form which causes the "application to be fried" .

Try running the while on another thread so that it pauses the new thread and not the thread of the view:

private void button1_Click(object sender, EventArgs e)
{
    System.Threading.Tasks.TaskFactory.StartNew(()=>{
      while(true)
      {
         // tu codigo
      }
    });
}

Now, you will have problems because you can not modify controls of the form in another thread that is not in the thread of the view. So whenever you change a control, whether for example changing the text of a Label or hiding a control, you have to use the Invoke method. For example:

private void button1_Click(object sender, EventArgs e)
{
    System.Threading.Tasks.TaskFactory.StartNew(()=>{
      while (1 == 1)
        {
            //...
            if (lstDispensador != null && lstDispensador.Count > 0)
            {
                foreach (CA_Dispensador dispensador in lstDispensador)
                {
                    //...
                    if (iContador <= 5)
                    {
                        //...

                        if (dispensador.Abierto)
                        {
                            // el metodo invoke nos evita el error de modificar un control en otro hilo
                            AbiertoLabel.Invoke(()=>{
                                AbiertoLabel.Text = "Abierto SI";
                            })
                        }
            //...
    });
}
    
answered by 01.11.2017 в 13:59