等待几秒钟而不阻止UI执行

use*_*691 53 c# timer wait

我想在两条指令之间等待几秒钟,但没有阻止执行.

例如,Thread.Sleep(2000)它不好,因为它会阻止执行.

我的想法是,我调用一个方法,然后等待X秒(例如20)监听一个事件.在20秒结束时,我应该根据20秒内发生的事情进行一些操作.

小智 84

我认为你所追求的是Task.Delay.这不会像Sleep那样阻塞线程,这意味着您可以使用异步编程模型使用单个线程来执行此操作.

async Task PutTaskDelay()
{
    await Task.Delay(5000);
} 

private async void btnTaskDelay_Click(object sender, EventArgs e)
{
    await PutTaskDelay();
    MessageBox.Show("I am back");
}
Run Code Online (Sandbox Code Playgroud)

  • 你甚至不需要 `PutTaskDelay()` 直接调用 `await Task.Delay(5000);` (3认同)
  • @Black对其他人的答案进行此类更改是不合适的。注释很好,但如果其他人更喜欢将代码提取到方法中,那是他们的决定。 (2认同)
  • @Black这是*你*改进的版本.重点是.如果您想出一种方法来改进解决方案,请为作者发表评论以决定进行更改,或者将您的替代方案作为您自己的答案发布(引用适当的衍生作品).将您的新版本编辑到其他人的答案中是不合适的. (2认同)
  • @Servy,好的,我找到你了 (2认同)

Oma*_*mar 25

我用:

private void WaitNSeconds(int segundos)
{
    if (segundos < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(segundos);
    while (DateTime.Now < _desired) {
         System.Windows.Forms.Application.DoEvents();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当心 DoEvents 中隐藏的邪恶。见 https://blog.codinghorror.com/is-doevents-evil/ 或 https://blog.codinghorror.com/is-doevents-evil-revisited/ (3认同)
  • 哇惊人的这个解决方案工作完美..谢谢你:) (2认同)
  • 这会消耗CPU。 (2认同)

Mat*_*att 12

这是使用另一个线程的好例子:

// Call some method
this.Method();

Task.Factory.StartNew(() =>
{
    Thread.Sleep(20000);

    // Do things here.
    // NOTE: You may need to invoke this to your main thread depending on what you're doing
});
Run Code Online (Sandbox Code Playgroud)

上面的代码需要.NET 4.0或更高版本,否则请尝试:

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
    Thread.Sleep(20000);

    // Do things here
}));
Run Code Online (Sandbox Code Playgroud)

  • 我只是在这里给我自己的旧答案添加评论,说我更喜欢其他答案中提到的异步方法,因为它们既更清洁又更好.如果您还没有读过异步,我强烈建议您这样做. (4认同)

Nic*_*ter 11

如果您无法将环境升级到.NET 4.5以获得对异步和等待API的访问权限,那么Omar的解决方案是不错的.也就是说,为了避免表现不佳,应该进行一项重要的改变.在调用Application.DoEvents()之间应该稍加延迟,以防止过多的CPU使用.通过增加

Thread.Sleep(1);
Run Code Online (Sandbox Code Playgroud)

在调用Application.DoEvents()之前,您可以添加这样的延迟(1毫秒)并阻止应用程序使用它可用的所有cpu周期.

private void WaitNSeconds(int seconds)
{
    if (seconds < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(seconds);
    while (DateTime.Now < _desired) {
         Thread.Sleep(1);
         System.Windows.Forms.Application.DoEvents();
    }
}
Run Code Online (Sandbox Code Playgroud)

*有关使用Application.DoEvents()的潜在缺陷的更详细讨论,请参阅https://blog.codinghorror.com/is-doevents-evil/.

  • 我用它来编写MVVM应用程序,因为Fw 3.5到4.5.1,即使有了所有新资源,有时候问题的简单解决方案也是最好的 (2认同)