使用Thread.Sleep()

时间:2016-10-25 14:09:24

标签: c#

(编辑 - 这仅用于学习目的,程序完全没有意义)

我试图让我的程序看起来像Thread.Sleep()使用随机生成的数字加载。它工作并等待时间但由于某种原因,它不会在所有睡眠发生之前在屏幕上显示历史变量。

它应该这样做

  • 打印登录...
  • 睡5-10秒
  • 打印验证详细信息......
  • 睡5-10秒
  • print已登录。

我追加历史字符串的原因是因为我想在屏幕上保留所有以前的版画,而且我是编程的新手,所以我认为这是最简单的方法。

        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;


    }

1 个答案:

答案 0 :(得分:2)

当您使用Thread.Sleep()时,它会阻止该线程。像红灯一样,在块被抬起之前,任何东西都无法移动。在简单的Windows窗体应用程序中,UI线程也会运行所有代码。因此,当您在方法中阻止线程时,您也会阻止UI。

执行此类操作的一个好方法是使用asyncawait运算符以及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。