ProgressBar does not activate Winform

1

I have a proguesBarr defined in my program as visible=false I want to show and activate when clicking create new game, this button is to initialize all user data in the database, with the Default data required which takes between 2 and 3 seconds. I have tried doing it in a normal timer ;

    public void InsertarPartida()
    {
        idPartida = maxID();
        String nombre = txtNuevaPartida.Text;
        fb.lblNombre = nombre;
        if (txtNuevaPartida.Text != "")
        {   
            progressBar1.Visible = true;
            timerBarraProgreso.Start();

            using (SQLiteConnection con = new SQLiteConnection(conectionString))...


            cargarDatosPorDefecto();
            tutorial = true;
            abrirInicioJuego();
        }
        else
        {
            mens.mensaje = "Introduce un nombre para poder dirigirnos a ti :)";
            mens.ShowDialog(this);
        }
    }

Here is the code of timer that I throw in the method;

    private void timerBarraProgreso_Tick(object sender, EventArgs e)
    {
        this.progressBar1.Increment(10);
    }

Another option that I have tried is to launch the progress bar timer in a secondary thread;

    private void lanzarHiloProgressBar()
    {
        this.progressBar1.Visible = true;
        this.progressBar1.ForeColor = Color.Blue;
        Thread t = new Thread(timerBarraProgreso.Start);
        t.Start();
    }
    
asked by Hector Lopez 28.03.2018 в 09:55
source

4 answers

2

You need to create an asynchronous method, which will load the data, something like this:

// en este método cargas tus datos
private async Task<List<tipodedatoquecargas>> CargaDatosPorDefecto()
{
     return await Task.Run(() => {
          // creas una lista donde cargaras tus dagos
          var listacargada = new List<tipodddatoquecargas>();
          // aquí va el código donde cargas tus datos
         return listacargada; // regresas la lista ya llena de datos
     };
}

Then, insert part you also do async:

private async Task CargarPartida()
{
    // para cargar los datos haces:
    var datos = await CargaDatosPorDefecto();
    // y haces lo que quieras hacer con los datos, no hagas llamadas a la UI aquí
}

And in the event where the call is made to LoadParty (Load or Click of a button), you change it like this:

private async void boton_Click(object sender, EventArgs e)
{
    this.progressBar1.Visible = true;
    await CargaPartida();
    this.progressBar1.Visible = false;
}

You set the progress bar to be "marquee". If you really need the progress bar to move forward, you'll have to change more logic.

I do not understand why the use of Tasks (async / await) is not recommended and things like thread and other outdated options are recommended

    
answered by 30.03.2018 / 04:52
source
3

You do not need a timer for the progress to reflect work, this control has the marquee mode assign the property

 progressbar1.Style = ProgressBarStyle.Marquee;

in this way when you start the query you will see the progress moving at the speed you define while the db is consulted, without the need of any timer

Style

ProgressBar.MarqueeAnimationSpeed

    
answered by 28.03.2018 в 15:46
1

According to what I have understood the problem you have is that while the query is running, the UI remains frozen. You want to show a progress bar but it does not update, it stays frozen like the rest of the UI while the query is not finished.

That's because you do both in the thread of the UI, it will not be fixed with a timer because you are still inside the thread of the UI.

Whenever I have to show progress with a progress bar or something else, I use the BackgroundWorker. The BackgroundWorker generates a thread apart from the UI and does not freeze the UI. However be careful because you can not update the UI from the thread of the worker (it is a separate thread and it will give you a petardazo).

Take a look at some tutorial of the BackgroundWorker and you will see that it is very easy to use: link

    
answered by 28.03.2018 в 16:01
1

Sorry about the theme of Easter, I left this topic a little aside, the solution I gave was something similar to what you mention @Luis;

    public async void InsertarPartida()
    {
        idPartida = maxID();
        String nombre = txtNuevaPartida.Text;
        fb.lblNombre = nombre;

        if (txtNuevaPartida.Text != "")
        {
            progressBar1.Visible = true;
            timerBarraProgreso.Start();
            //progressBar1.Style = ProgressBarStyle.Marquee;
            //Se lanza una tarea para intentar activar la puta barra de progreso

            await Task.Run(() =>
            {      
            using (SQLiteConnection con = new SQLiteConnection(conectionString))...
            cargarDatosPorDefecto();
            tutorial = true;
            });
            abrirInicioJuego();

        }
        else
        {
            mens.mensaje = "Introduce un nombre para poder dirigirnos a ti :)";
            mens.ShowDialog(this);
        }
    }

What I did was to introduce the lines of code that required time to execute in a task so that they do not block the main thread and the progressBar could be displayed, as @Luis says what you try to do of thread is something outdated.

    
answered by 02.04.2018 в 08:31