在Thread.Sleep()期间保持UI响应
本文关键字:UI 响应 Thread Sleep | 更新日期: 2023-09-27 18:07:30
背景:我正在编写一个应用程序,它遍历服务器列表并获取每台机器的各种详细信息。在迭代过程中,我需要更新表单上的各种控件(以显示获取信息的摘要)。因为它正在遍历一个列表,所以我调用了Thread.Sleep(),让用户在查询下一台机器之前有时间阅读信息。下面是我的代码:
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);
对于更新表单上的控件,这工作得很好,但在Thread.Sleep()期间,UI被锁定。当然,如果在一个单独的任务上调用thread . sleep (), UI线程仍然保持未阻塞?
任务。延迟应该适合你的需要。
改变Task.Factory.StartNew(() =>
Task.Factory.StartNew(async () =>
和改变
Thread.Sleep
await Task.Delay
如果您将UiScheduler
传递为TaskScheduler
,则该任务正在UI线程上运行。所以,当你调用Thread.Sleep
时,UI线程被完全阻塞了。
如果您想延迟,使用await Task.Delay(10000)
代替异步延迟。
这将使从Task.Factory.StartNew
返回的任务成为Task<Task>
,因为它不像Task.Run
那样构建async-await。要解决这个问题,请在返回的Task上使用Task.Unwrap
:
Task<Task> TestTask = Task.Factory.StartNew(async () =>
{
// ...
await Task.Delay(10000);
// ...
}, CancellationToken.None, TaskCreationOptions.None, UiScheduler);
Task actualTask = TestTask.Unwrap();
使用Task.Delay
代替Thread.Sleep
查看此链接了解更多详情