2013-07-22 41 views
1

众所周知,在UI线程和工作线程之间需要沟通的情况下,由于线程安全(句柄重建),必须创建一个隐藏窗口。安全和良好的设计AllocateHWND响应多个线程?

对于举例说明:

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

    过程RefreshStat(VAR消息:TMessage);消息WM_REFRESH;

  • 里面RefreshStat,在情况下,当只有1个后台线程我可以很容易地使用LW参数映射任务ID和位置。

我不知道标题说我想知道什么,而是让,如果我们有一个具有运行多个后台任务的应用程序的想象。
在我的情况下,我使用TProgressBar来报告完成的进度。

请问AllocateHwnd是否保证所有消息都没有竞争条件到达隐藏窗口?
如果两个或多个任务同时发布消息会发生什么?

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

我希望问题很清楚。

+0

不要将THandle用于窗口。使用HWND。您可以使用THandle来传递给CloseHandle,即Windows类型的HANDLE。 –

+0

@Matheus,你如何从那个隐藏窗口更新那些进度条?换句话说,你想如何与窗体同步隐藏的窗口?这不是太复杂吗?您可以直接将['progress bar messages'](http://msdn.microsoft.com/cs-cz/library/windows/desktop/ff485990(v = vs.85).aspx)发布到控制你的表格。 – TLama

+0

@TLama问题是窗口重新创建。后台任务不能使用VCL窗口句柄,因为它可以并且经常会被破坏并重新创建。因此,表单需要一个隐藏的窗口,其生命周期是确定性的。 –

回答

5

与线程关联的消息队列是线程安全队列。来自多个其他线程的同步和异步消息都可以安全地传递,不会产生有害的日期比赛调用Windows消息API函数(如SendMessage和PostMessage)时,不需要任何外部同步。

如果两个线程同时发布或发送消息到同一个窗口,那么不能保证哪个消息将首先被处理。这就是所谓的良性竞赛条件。如果你想要一个消息在另一个之前被处理,那么你必须强加一个排序。

+0

[+1]我最感兴趣的是我认为,因为AllocatHwnd创建了一个新窗口,它应该控制所呈现的情况。 – EProgrammerNotFound

+0

由于TLama提到了这个问题,你真的认为有必要为这种情况使用AllocateHwnd吗? – EProgrammerNotFound

+0

AllocateHWnd或TThread.Queue或TThread.Synchronize –