【问题标题】:How to clear keyboard buffer from stale messages如何从过时的消息中清除键盘缓冲区
【发布时间】:2023-03-22 15:37:02
【问题描述】:

我的 WinForms 应用程序有一个按钮。此按钮具有加速键(例如 Alt+L)。当按下按钮时,我处理 Click 事件并禁用 UI 以防止进一步的按钮点击,直到处理完成。但是,当使用键盘按下加速键时,这些击键将排队并在 UI 再次启用时立即得到处理。我不想要这个。我的问题是如何清除/刷新键盘缓冲区?

如果我使用 KeyPress 或 KeyDown 吃掉那些我不知道什么时候收到的字符。我只想抑制在我仍在处理第一个 Click 事件时到达的旧/陈旧消息。

【问题讨论】:

  • 禁用按钮并且击键设法推动它?在重新启用按钮之前尝试Application.DoEvents
  • 听起来你正在做的工作可能希望在它自己的线程上运行以释放用户界面线程并保持消息泵运行。 Application.DoEvents 可能会有所帮助。但另一个线程似乎也是个好主意。
  • @madmik3:同意创建一个新线程。 Application.DoEvents 有点像黑客。多线程是更优雅的解决方案。 @Jacob:但您首先需要确认 UI 阻塞确实是问题所在。从问题中不清楚您是否正确地做其他所有事情。
  • @Cody:也许 UI 被禁用的事实并不相关。我看到的是,如果用户键入的速度快于应用程序可以处理的速度,或者它无法处理事件,则击键将排队等待稍后处理。我不想要这个。

标签: winforms keyboard buffer flush


【解决方案1】:

是的,你的问题理论确实与我和 madmik3 在上面的评论交流中提出的一致。您的应用程序在 UI 线程上所做的工作量有效地阻止了它处理其他事件,包括用户的击键。每当您的应用程序完成其耗时的前台任务时,这些都会排队等待稍后执行。这些是现代的、先发制人的多任务操作系统的危险。当然,在不发布您的实际代码的情况下,我或其他任何人所能做的最好的事情就是根据我们的经验推测问题所在。

确认是否确实如此的快速检查是将Application.DoEvents 扔到您的处理循环中。这将允许操作系统立即处理击键,因为按钮已被禁用,这将全部失败。 (Click 事件,无论是由鼠标还是键盘快捷键启动,对于将其Enabled 属性设置为“False”的Button 控件都不会引发。)这是最接近于“刷新缓冲区”。我怀疑您是否会收到 KeyDownKeyPress 事件,直到完成任何长时间运行的任务。

如果这样可以解决问题,长期的解决方案是生成一个新线程并在那里执行您需要执行的任何处理,而不是在您的 UI 线程上执行。这将阻止您阻塞您的 UI 线程,并且假设 Button 控件被正确禁用,导致按键被丢弃,因为他们“点击”的按钮处于不可点击状态。创建新线程的最简单方法是使用BackgroundWorker component。该文档包含一个非常好的示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 2023-03-31
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多