problema control.invoke ()

Im trying to update a progress bar while doing some data type checks on a separate thread and there seems to be a delay between what value the progress bar is at and the value which is actually show.

The following code is executed by the non-GUI thread and is used to raise the event.

    protected virtual void OnUpdateProgressBar(object sender, ProgressBarEventArgs e)
    {
        EventHandler<ProgressBarEventArgs> TempHandler = UpdateProgressBar;

        //Avoid possible race condition.
        if (TempHandler != null)
        {
            TempHandler(this, e);
        }
    }

I have created a separate class for updating the progress bar and when i create an instance of it, i pass a reference to the progress bar. Below is the entire class.

public class ProgressBarChanged
{
    ProgressBar statusBar;

    public ProgressBarChanged(ProgressBar pb)
    {
        statusBar = pb;
        statusBar.Value = 0;
    }
    public ProgressBarChanged()
    {
    }

    public void subscribeToEvent(DataVerification test)
    {
        test.UpdateProgressBar += new EventHandler<ProgressBarEventArgs>(incrementPB);
    }

    public void incrementPB(object sender, ProgressBarEventArgs e)
    {
        Action action = () =>
        {
            if (e.CurrentRow == e.FinalRow - 10)
            {
                int i = 5;
            }
            statusBar.Maximum = e.FinalRow;
            statusBar.Value = e.CurrentRow;
        };

        if(statusBar.InvokeRequired)
           statusBar.Invoke(action);
        else
            action();
    }
}

I have uploaded a screen shot showing the progress bar and the actual values. Any ideas???

Muchas Gracias

enter image description here

preguntado el 09 de marzo de 12 a las 16:03

Has probado con statusBar.Invoke(incrementPB, sender, e); ? -

Tried both statusBar.Invoke(incrementPB,sender,e); and statusBar.Invoke(incrementPB(sender,e)); neither work. -

@Ken2K, thanks for sorting out the picture. -

Perhaps if you could remove the updating of the maximum value, the internal processing of statusbar will be faster. I mean, if you change the maximum at every event, what is the impact on the recalculation of the progress? -

@Steve: Fair point, ill see about only updating it once as well. Thanks for your help. -

2 Respuestas

The progessbar is a simple feedback to the user, not a piece of exact instrumentation. It's a pacifier.

It also incorporates it's own async logic to update the screen (independent of the message loop). This makes that it may run a little behind.

¿Cual es el problema?

To get more accurate results, divide your range into < 100 segments and do fewer updates.

respondido 09 mar '12, 16:03

@At present the event is getting raised after each row is processed = 130,000 times. ill try, As you have suggested, and raises it less than 100 times and see if that solves the issue. Thanks for your help - hans rudel

@HansRudel If the Value is updated only 100 times (not 130k times), it'll also reduce CPU consumption a lot, so it's a good idea. - ken2k

A delay is pretty normal. After all, invoking a method in the UI thread means Windows will dispatch a message and if your thread is fast enough (and CPU consuming) then it'll appear faster than UI.

respondido 09 mar '12, 16:03

:Thanks for replying. According to Mr Skeet's post here stackoverflow.com/questions/229554/… i though that the thread would wait for the GUI to process the progress bar update. Or does it change the internal value and then take time to actually show the update? If so is there a way around this delay? - hans rudel

The thread will wait for the PB to accept the new value. The visual updating happens separately. - henk holterman

Try to call Refresh after each value change (but it's not very optimal to have progbar refreshed this way). - ebutusov

Even if he calls Refresh() from inside the Action that won't change and it can't be called from another thread... - Adriano Repetti

@Adriano - It certainly could be invoked. - Sabueso de seguridad

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.