没有同步从线程读取值是否安全?

Ben*_*iss 3 delphi multithreading vcl

我想知道从主线程外的VCL控件读取值是否安全.

比方说,我看行之后行(或它的Caption属性)从TMemo/TEdit从线程控制(没有TThread.Synchronize),但也取得了一定TMemo/TEdit控制已被禁用和/或它的唯一标志已启用读取.

它会安全吗?

Dav*_*nan 5

不,这不安全.通过调用窗口过程(使用Perform方法),传递WM_GETTEXTLENGTH和来读取备忘录和编辑控件中的内容WM_GETTEXT.Win32要求在创建窗口的线程上执行此类代码,在本例中为主线程.因此,当您Text从工作线程读取属性时,您会破坏该规则,因为您调用Perform了工作线程,然后在错误的线程上执行窗口过程.

您可能会认为您可以使用SendMessage传递WM_GETTEXTLENGTH/WM_GETTEXT来安排在主线程上执行窗口过程.但这是一个令人讨厌的竞争条件.您需要使用窗口句柄SendMessage,但访问Handle工作线程上的属性不是线程安全的.这必须在主线程上完成,否则VCL窗口重新创建可能导致窗口由工作线程创建.GUI窗口必须由主线程创建.

  • @sertac VCL窗口重新创建可导致在错误的线程上重新创建窗口 (2认同)
  • @David,我完全同意你应该只阅读主线程中的文本.同时我不认为你的答案是准确的.首先,从任何线程向窗口发送/发送消息是安全的(消息将被放置到窗口队列中,并且将在创建控制窗口的线程中处理).换句话说,SendMessage将使当前线程与main同步.第二点是备忘录不发送消息,它调用Perform.实际上它直接调用消息处理程序(没有消息队列).这就是它不安全的原因. (2认同)