C#休眠500毫秒

7
请问如何暂停程序500毫秒后继续执行?我了解到使用Thread.Sleep(500)会阻塞GUI线程。使用计时器可以触发回调函数,但我只想等待500毫秒然后继续执行下一条语句。请给予建议。
编辑:我需要在状态栏显示500毫秒的消息,然后将消息更新为不同的消息。对不起,我是指500而不是50。
编辑:我理解你们所说的一切。但是:“[我只想等待500毫秒然后继续执行下一条语句]”因为这个时间间隔很短,我会在主GUI线程上使用Thread.Sleep(500)。否则,我将不得不重写大量代码来适应这个短暂的500毫秒间隔。
编辑:我将尝试重新格式化我的状态消息,以便不需要暂停。
6个回答

6
Hmya,你想做的事情与Windows编程模型非常不兼容。本地Windows程序是事件驱动的。你的程序总是空闲的,在由Application.Run()启动的循环中等待Windows告诉它发生了一些有趣的事情需要响应,如绘图请求、鼠标点击、计时器到期等。
你的程序应该对此作出响应并过滤出你感兴趣的内容。当你在窗体上放置一个按钮时,你总是对Click事件感兴趣,这个事件是由Windows发送的MouseDown通知消息生成的。你的Click事件处理程序运行一些你编写的自定义代码,比如更新状态栏消息。
半秒钟后更新状态栏消息没有太多意义。在这500毫秒内发生了什么导致你的程序对事件的响应方式发生了变化?你可以调用StatusBar的Update()方法使新消息可见,然后调用System.Threading.Thread.Sleep(500)来实现你想要的效果。你可以这样做,但是Windows会出现“未响应”的提示,让你的程序死掉几秒钟。
但这没有太多意义,那半秒钟内什么都没发生,你的程序的状态也没有改变。它不可能改变,因为它已经死了,无法接收任何消息来改变状态。
好吧,我能帮你的就这么多了。请更新你的问题并解释为什么需要这样做。以防万一:如果你考虑这样做来假装做了什么重要的事情,你的用户不会感到印象深刻。她最终会注意到你的界面死掉了半秒钟,没有任何东西可以展示。

我正在尝试将应用程序状态信息分块呈现给用户。我有完整的信息,但我认为最好分两步呈现,而不是一次性呈现大量信息。[您的评论非常有帮助,谢谢]。 - iTEgg
@ikurtz:这是否意味着您想向用户通知您在代码中采取的重要步骤?那只需要几毫秒,对于用户来说太快了吗?不,她不感兴趣,她关心的是结果。您已经做到了正确的事情,确保它真的很快完成。干得好,您的同行程序员会欣赏它。但不是您的用户。好吧,她确实会欣赏,她期望如此。 - Hans Passant
谢谢。我很喜欢你的回复,因为它让我重新审视了我的行动和目标。有时候,提供思路比编写代码解决问题更好。 - iTEgg
麦迪逊?威斯康星州?那里很不错,但我在英国! - iTEgg

5
你有两个选择:
  • 像你建议的那样,使用计时器。将你的方法分成两个方法,foo1和foo2。使用foo1启动计时器,在回调中运行foo2。
  • 使用BackgroundWorker在工作线程上使用Thread.Sleep来运行整个函数。
从你的更新中,似乎你唯一想做的事情就是更改单个字段。我肯定会推荐第一种方法:使用计时器。为此任务启动BackgroundWorker过于繁琐,并且只会给你带来不必要的额外工作和复杂性。

问题是我不想要回调函数,我只是想在暂停后继续执行下一行代码。 - iTEgg
@ikurtz:为什么你不想要回调函数?如果你避免使用回调函数的原因是为了让代码保持在一起,你可以将回调函数嵌入到第一个函数中。但我觉得你唯一满意的答案就是有人告诉你使用 Application.DoEvents()。这可能会起作用,但这不是最好的方法。 - Mark Byers

4

不要直接暂停 UI 500 毫秒,你可以使用 BackgroundWorker。这将导致你的回调在一个单独的线程中运行,在这个线程中,你可以使用 Thread.Sleep 来暂停它而不会阻塞 UI。然后当你完成时,只需用新消息更新状态栏。


2

如果能提供更多背景信息会更有帮助。

Thread.Sleep(50)将暂停当前线程50毫秒。如果您在UI线程中执行此操作,则会使UI在50毫秒内冻结。但是,如果您使用不同的线程来处理此过程,则在该线程上调用Sleep将暂停它50毫秒而不会冻结您的UI线程。

请参考Marc的答案:这个问题,了解如何使用BackgroundWorker实例来完成您需要的操作。


2

在C#中,您最好使用计时器并触发回调。

在F#中,有一种非常棒的方法可以实现您想要的功能,请参见

客户端上的F#异步

它展示了如何编写直线代码并让语言为您处理回调。


0
你需要分配另一个线程。在该线程中,你需要Sleep(500)并更改所需的数据。注意:你需要使用原始线程的调度程序,因为与UI相关的数据通常应该从GUI线程更新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接