简体   繁体   中英

How to execute wait time on a seperate thread to stop UI from freezing

I'm trying to increment the floor, and every time the status of the floor should change and show on the floor slowly increasing to the desired floor. But the floor just waits then jumps straight to he desired floor without me seeing it gradually increment. I'm assuming it's because the UI is frozen every time it hits sleep and therefore I don't see the gradual incrementing.

So how do I execute the wait on another thread (if thats even the problem) to stop the UI from not freezing?

Here's my code:

        while (floor > elevator.currentFloor)
        {
            elevator.currentFloor++;
            changeStatus(elevator);
            currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor;
            System.Threading.Thread.Sleep(500);
        }

Assuming you're using Win Forms, move your code into a System.Windows.Forms.Timer . If not, use the appropriate .NET timer .

    while (floor > elevator.currentFloor)
    {
        elevator.currentFloor++;
        changeStatus(elevator);
        currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor;
        await Task.Delay(500);
    }

As you can see, we are using await Task.Delay(500) instead of Thread.Sleep(500) . These both achieve the same thing, that is stops execution of your code for 500ms.

The difference is that Thread.Sleep(500) is what we call a blocking call. It tells your thread (UI thread, the thread that draws on your screen) to go to sleep. This means that your UI can't be updated during that time.

On the other hand, await means, there is some code here that will tell you when its done. Until its done, go outside and do something else (like update the UI). Task.Delay(500) means, in 500ms time, tell someone that you are "done".

The difference therefore is that during those 500ms, this solution will allow your UI thread to do all its housekeeping stuff, like update the screen, respond to the mouse etc etc, whilst your code has the very important UI thread go on holiday (leaving your UI closed to business).

Okay so thanks to Aron, I had to make the method into an async method to be able to use await - and now it works! I can 'wait' whilst updating my UI. Here's the edited code:

    async void move(int floor)
    {
        DateTime now = DateTime.Now;
        TimeSpan duration;
        while (floor > elevator.currentFloor)
        {
            await Task.Delay(500);
            elevator.currentFloor++;
            changeStatus(elevator);
            currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor;
            duration = DateTime.Now - now;
            timeLbl.Text = "Time elapsed: " + duration.TotalMilliseconds.ToString() + "ms";
        }

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