【发布时间】: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 个后台线程,我可以轻松使用L和W参数来映射任务ID 和位置。
我不知道标题是否说明了我想知道的内容,但让我们想象一下,如果我们有一个运行多个后台任务的应用程序。
就我而言,我使用TProgressBar 报告完成的进度。
AllocateHwnd 是否保证所有消息在没有竞争条件的情况下到达隐藏窗口?
如果两个或多个任务同时发布消息会怎样?
如果这需要手动控制,不知道除了在自定义消息中创建另一个消息循环系统之外,是否还有其他事情要做。
我希望问题足够清楚。
【问题讨论】:
-
不要将 THandle 用于窗口。使用 HWND。您将 THandle 用于可以传递给 CloseHandle 的东西,即 Windows 类型 HANDLE。
-
@Matheus,你想如何从那个隐藏窗口更新那些进度条?换句话说,您希望如何将隐藏窗口与您的表单同步?那会不会太复杂了?将
progress bar messages直接发布到表单上的控件可能就足够了。 -
@TLama 问题是重新创建窗口。后台任务不能使用 VCL 窗口句柄,因为它可以而且经常会被销毁并重新创建。因此表单需要一个隐藏窗口,其生命周期是确定的。
-
@David,在创建/销毁进度条时,不会重新创建表单。为什么会发生?而且我看不出我为什么要自己破坏这种监控表格的原因。这同样适用于进度条。为什么我会破坏正在运行的任务的进度条?也许我遗漏了一些东西,但我看不出将消息直接发布到 PB 有什么危险。
-
@TLama 我们不是在谈论销毁 VCL 对象,而是重新创建窗口。许多属性更改会导致重新创建窗口。
标签: multithreading delphi winapi delphi-6