【问题标题】:Is safe and good design AllocateHWND to respond more than one thread?安全且良好的设计 AllocateHWND 是否响应多个线程?
【发布时间】:2013-07-21 18:20:06
【问题描述】:

众所周知,当需要在 UI 线程和工作线程之间进行通信时,由于线程安全(句柄重构),必须创建一个隐藏窗口。

举例:

  • Form1 有 N 个动态创建的 TProgressBar 实例,与后台运行的名称相同。
  • 始终保证WM_REFRESH 只会在任务线程中被调用。
  • Form1 具有分配以下过程的H : THandle property

    procedure RefreshStat(var Message: TMessage);消息 WM_REFRESH;

  • RefreshStat 内部,如果只有1 个后台线程,我可以轻松使用LW 参数来映射任务ID 和位置。

我不知道标题是否说明了我想知道的内容,但让我们想象一下,如果我们有一个运行多个后台任务的应用程序。
就我而言,我使用TProgressBar 报告完成的进度。

AllocateHwnd 是否保证所有消息在没有竞争条件的情况下到达隐藏窗口?
如果两个或多个任务同时发布消息会怎样?

如果这需要手动控制,不知道除了在自定义消息中创建另一个消息循环系统之外,是否还有其他事情要做。

我希望问题足够清楚。

【问题讨论】:

  • 不要将 THandle 用于窗口。使用 HWND。您将 THandle 用于可以传递给 CloseHandle 的东西,即 Windows 类型 HANDLE。
  • @Matheus,你想如何从那个隐藏窗口更新那些进度条?换句话说,您希望如何将隐藏窗口与您的表单同步?那会不会太复杂了?将progress bar messages 直接发布到表单上的控件可能就足够了。
  • @TLama 问题是重新创建窗口。后台任务不能使用 VCL 窗口句柄,因为它可以而且经常会被销毁并重新创建。因此表单需要一个隐藏窗口,其生命周期是确定的。
  • @David,在创建/销毁进度条时,不会重新创建表单。为什么会发生?而且我看不出我为什么要自己破坏这种监控表格的原因。这同样适用于进度条。为什么我会破坏正在运行的任务的进度条?也许我遗漏了一些东西,但我看不出将消息直接发布到 PB 有什么危险。
  • @TLama 我们不是在谈论销毁 VCL 对象,而是重新创建窗口。许多属性更改会导致重新创建窗口。

标签: multithreading delphi winapi delphi-6


【解决方案1】:

与线程关联的消息队列是线程安全队列。来自多个其他线程的同步和异步消息都可以安全地传递,没有有害的日期竞争。调用 SendMessage 和 PostMessage 等 Windows 消息 API 函数时,无需任何外部同步。

如果两个线程同时向同一个窗口发布或发送消息,则无法保证哪个消息将首先被处理。这就是所谓的良性竞争条件。如果您希望在另一条消息之前处理一条消息,则必须强制执行排序。

【讨论】:

  • [+1] 让我感兴趣的是,我认为由于 AllocatHwnd 创建了一个新窗口,它应该控制呈现的情况。
  • 既然 TLama 谈到了这个主题,你真的认为有必要在这种情况下使用 AllocateHwnd 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多