Keeping UI responsive during a Thread.Sleep() [duplicate]

丶灬走出姿态 提交于 2019-12-10 15:55:54

问题


Background: I am writing an application that iterates through a list of servers and obtains various details about each machine. During the iteration, I need to update various controls on the form (to display a summary of the obtained information). Because it is iterating through a list, I have called a Thread.Sleep() to allow the user time to read through the information before the next machine is interrogated. Below is my code:

Task TestTask = Task.Factory.StartNew(() =>
            {
                foreach (String IpAddress in ServersToCheck)
                {
                    if (IpAddress != String.Empty)
                    {
                        ServerBeingCheckedLabel.Text = IpAddress;
                        if (PingServer(IpAddress) == true)
                        {
                            PingChar_Label.ForeColor = Color.Green;
                            PingChar_Label.Text = "a";
                            CheckPermissionsAreValid(IpAddress);
                        }
                        else
                        {
                            PingChar_Label.ForeColor = Color.Red;
                            PingChar_Label.Text = "r";
                            PermChar_Label.ForeColor = Color.Red;
                            PermChar_Label.Text = "r";
                        }
                    }
                }
                Thread.Sleep(10000);
                this.BackColor = FormBackGroundColor;
                TestButton.Enabled = true;
                RunTimer.Enabled = true;
            }, CancellationToken.None, TaskCreationOptions.None, UiScheduler);

This works fine regarding updating the controls on the form, but during the Thread.Sleep() the UI locks up. Surely if the Thread.Sleep() is called on a separate task, the UI thread has remained unblocked?


回答1:


Task.Delay should suit your needs.

Change

Task.Factory.StartNew(() =>

to

Task.Factory.StartNew(async () =>

and change

Thread.Sleep

to

await Task.Delay



回答2:


If you pass the UiScheduler as TaskScheduler then that task is running on the UI thread. So yes, the UI thread is completely blocked when you call Thread.Sleep.

If you want to delay use await Task.Delay(10000) instead to delay asynchronously.

That will make the task returned from Task.Factory.StartNew a Task<Task> because it wasn't build with async-await in mind unlike Task.Run. To fix that use Task.Unwrap on the returned Task:

Task<Task> TestTask = Task.Factory.StartNew(async () =>
{
    // ...
    await Task.Delay(10000);
    // ...
}, CancellationToken.None, TaskCreationOptions.None, UiScheduler);

Task actualTask = TestTask.Unwrap();



回答3:


use Task.Delay instead of Thread.Sleep checkout This link for more details



来源:https://stackoverflow.com/questions/31960351/keeping-ui-responsive-during-a-thread-sleep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!