(编辑 - 这仅用于学习目的,程序完全没有意义)
我试图让我的程序看起来像Thread.Sleep()
使用随机生成的数字加载。它工作并等待时间但由于某种原因,它不会在所有睡眠发生之前在屏幕上显示历史变量。
它应该这样做
我追加历史字符串的原因是因为我想在屏幕上保留所有以前的版画,而且我是编程的新手,所以我认为这是最简单的方法。
private void Loading()
{
Random rnd = new Random();
int wait1 = rnd.Next(5000, 10000 );
history = "Logging in...\n";
historyLbl.Text = history;
System.Threading.Thread.Sleep(wait1);
int wait2 = rnd.Next(5000, 10000);
history = history + "Verifying Details...\n";
historyLbl.Text = history;
System.Threading.Thread.Sleep(wait2);
history = history + "Logged in.\n";
historyLbl.Text = history;
}
答案 0 :(得分:2)
当您使用Thread.Sleep()
时,它会阻止该线程。像红灯一样,在块被抬起之前,任何东西都无法移动。在简单的Windows窗体应用程序中,UI线程也会运行所有代码。因此,当您在方法中阻止线程时,您也会阻止UI。
执行此类操作的一个好方法是使用async
和await
运算符以及Task.Delay()
// Note the change in signature
private async Task Loading()
{
Random rnd = new Random();
int wait1 = rnd.Next(5000, 10000 );
history = "Logging in...\n";
historyLbl.Text = history;
await Task.Delay(wait1);
int wait2 = rnd.Next(5000, 10000);
history = history + "Verifying Details...\n";
historyLbl.Text = history;
await Task.Delay(wait2);
history = history + "Logged in.\n";
historyLbl.Text = history;
}
它使用一种特殊的语言功能,基本上可以等待一个完整的单独的线程,并在完成后返回到您的代码。这就是用户界面不会冻结的原因。
好的,我错了。异步和等待总是有点神秘,我想我只是假设。
请注意,无论您何时调用此方法,您都需要等待它。例如,如果按下按钮单击,则需要更改按钮单击事件处理程序
// async void is a special pattern for event handlers, to allow them to use async.
// in general you should always use async Task
private async void Button_Click(object sender, EventArgs e)
{
await Loading();
}
但更大的问题是你为什么要这样做?用户永远不想等待更长时间。每隔一段时间我就会使用Task.Delay()
来让我的UI线程赶上来,但这最多只能持续20ms。