问题描述
我是线程新手.我正在使用第3方库,该库使用的线程有时会调用我提供的过程.
I'm new to threads. I'm using a 3rd party library that uses threads which at times call a procedure I've provided.
当线程调用TLabel.Caption时,如何更新该程序中的TLabel.Caption?
How do I update update a TLabel.Caption from my procedure when its called by the thread?
如果我在其他地方调用过InitializeCriticalSection,它是否简单
If I've called InitializeCriticalSection elsewhere, is it as simple as
EnterCriticalSection(CritSect);
GlobalVariable := 'New TLabel.Caption';
LeaveCriticalSection(CritSect);
然后在我的主线程中:
EnterCriticalSection(CritSect);
Label1.Caption:= GlobalVariable;
LeaveCriticalSection(CritSect);
但是,如何获得要调用的主线程代码?线程可以使用SendMessage吗?还是有更好/更简便的方法(.OnIdle可以检查线程设置的标志吗?)
But, how do I get the main thread code to be called? The thread can use SendMessage? Or is there some better/easier way (.OnIdle could check a flag set by the thread?)
谢谢.
推荐答案
关键部分用于序列化对一段代码的访问.对于更新图形用户界面,应注意只有主线程才应更新GUI元素.
Critical Sections are used to serialize accessing to a piece of code. For updating graphical user interface, you should take note that only the main thread should update GUI elements.
因此,如果您的线程需要更新GUI元素,则应将其委派给主线程.为此,您可以使用不同的技术:
So if your thread needs to update a GUI element, it should delegate this to the main thread. To do so, you can use different techniques:
最简单的方法是在线程代码中使用Synchronize方法.调用Synchronize时,线程将暂停,您提供给Synchronize的代码将在主线程的上下文中执行,然后您的线程恢复.
The simplest one is using Synchronize method in your thread code. When Synchronize is called, your thread is paused, the code you provided to Synchronize will be executed in the context of the main thread, and then your thread resumes.
如果您不希望每次调用该代码段时线程都停止,则可以使用Queue方法.队列将您的请求发送到目标线程(这里是主线程)的消息队列,因此您的线程不会停止,但是UI可能不会立即更新,这取决于拥挤的主线程的消息队列.
If you don't like your thread get stopped every time that piece of code is called, then you can use Queue method. Queue sends your request to the message queue of the destination thread (here main thread), so your thread will not stop, but the UI might not get updated immediately, depending on how crowded main thread's message queue is.
实现此目的的另一种方法是使用SendMessage或PostMessage API函数将自定义Windows消息发送到主线程.在这种情况下,您必须定义一个自定义消息,并在需要更改UI元素时将其发送到主线程.您的主线程应为该类型的消息提供消息处理程序,并处理收到的消息.结果类似于使用Queue方法.
Another way to achieve this is to send custom Windows messages to the main thread using SendMessage or PostMessage API functions. In that case, you have to define a custom message, and send it to the main thread whenever you need to change a UI element. Your main thread should provide a message handler for that type of message, and handle the received messages. The consequence is something similar to using Queue method.
这篇关于在线程中使用EnterCriticalSection更新VCL标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!