Delphi - 如何在任务执行时监听和处理WMDeviceChange消息?

时间:2009-03-15 15:00:00

标签: multithreading delphi

我遇到了几乎同时连接的两个驱动器无法处理的问题。我实际上修复了获取驱动器模型的旧scsi方法,但我有一种感觉,我即将遇到同样的问题。

如果某个任务正在执行,例如我检查过该驱动器是否是某个特定设备,并且不幸的是,如果该设备刚刚连接,则会花费一些时间。执行过程中发出的WM_DEVICECHANGE消息根本不会被接收。

即使我必须存储消息并将其排队以进行处理,我也不确定如何在执行另一个任务时启用应用程序。我的第一个猜测是我必须使用线程吗?

我有一个WM_DEVICECHANGE处理程序,用于侦听设备到达和设备删除。它获取并返回一个驱动器号并将其传递给将驱动器添加到组合框的代码,然后检查它是psp还是只是可移动驱动器,然后有一个消息对话框询问用户是否要选择此驱动器或不。

我也有一种感觉,消息对话框会阻止处理WM_DEVICECHANGE消息,但在我编写新方法之前,我无法测试它。

无论如何,我想也许有人能理解我的意思并指出我正确的方向。我担心尝试使用线程会导致他们自己的一小部分问题?

1 个答案:

答案 0 :(得分:2)

我不会为此使用线程。只需将您给出的答案提供给其他问题,并从中创建一个更通用的解决方案。

如果您使用一个GUI线程,您将不会错过任何消息 - 您只需稍微延迟处理它们。但是,您可能不会在处理一个消息时忽略其他消息并调用 Application.ProcessMessages()或涉及计时器 - 这就是您目前遇到的情况。

当模态对话框处于活动状态时,您会运行辅助消息循环,并且在处理上一个消息循环时可能会收到新的 WM_DEVICECHANGE 消息。我会怎么做才能解决这个问题:

  1. 在您的应用程序中创建未完成的驱动器请求记录列表,该记录可以包含驱动器号,所有必要的附加数据以及请求到期的时间值。

  2. 收到 WM_DEVICECHANGE 消息后,您将新的请求记录添加到列表中,并设置驱动器号并将超时值设置为当前时间加上30秒。每个驱动器号应该只在列表中一次。立即重新删除驱动器时删除请求的加分点。您还需要启用计时器。

  3. 在计时器事件处理程序中,首先禁用计时器,然后执行代码以处理请求。如果成功,则从列表中删除该请求。如果它不成功,但当前时间超过了超时请求,则从列表中删除该请求,提醒用户存在问题。如果在超时之前还有剩余时间,请将请求保留在列表中,以便下次重试。最后,重新启用计时器,但前提是请求列表不为空。

  4. 使用这种方法,您将能够处理尽可能多的并发请求,因为您的请求列表可以保存条目。没有需要来使用线程。使用线程当然会提高应用程序的响应能力,但是您是否想要为增加的复杂性增加自己的负担是由您来决定的。 StackOverflow上已经有很多与线程相关的问题,浏览它们以了解您将要处理的新问题。