简体   繁体   中英

Why exactly is UI not updating in time without background worker?

I wrote a single threaded program (winforms meh) and am expecting it to behave like this:

  1. Mainform starts Progress display form
  2. Progress form is rendered fully
  3. Progress form receieves event operationStarted which adds a picture of spinning circle to the form
  4. Long lasting operation starts
  5. Progress form receives event operationCompleted or operationFailed and sets appropriate image

What happens is messy.

  1. Mainform starts Progress display form
  2. Progress form is not rendered fully!
  3. Program hangs for a while
  4. When long lasting operation is complete UI updates

Why the lag with updating windows form?

This is reduced code if necessary

    private bool Run(int commandIndex, string fullCommand)
    {
        if (operationStarted != null)
            operationStarted(commandIndex);

        // start long lasting external process

        if (exitCode != 0)
        {
            if (operationFailed != null)
                operationFailed(commandIndex, Error);

            return false;
        }

        if (operationCompleted != null)
            operationCompleted(commandIndex);

        return true;
    }

operationStarted, operationFailed & operationCompleted are set correctly to update the appropriate images.

This is vastly simplified but I think it should suffice.

Windows is driven by messages which is handled in a queue system.

When you show a window, one or more messages is put into a queue and has to be processed.

One of these messages is going to be a paint message. In response to this message your program is supposed to paint the window (or something inside it) on the screen.

The way the queue system is processed is that your form is owned by a thread that is continuously doing something like:

while (true)
{
    var message = GetNextMessage();
    if (message == none) break;
    ProcessMessage(message);
}

One of the messages this loop handled was a message instructing your program that the user clicked on a button a form.

In response to this, .NET routes this message as an event to your event handler, typically something like "button1_Click", which then executes.

Until your event handler, this click method, returns, this loop is not processing any messages.

As such, if that button click event is doing something lengthy you're said to be "blocking the UI", which is basically "you're not returning in an orderly fashion back to the message loop".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM