在没有同步的情况下从线程读取值是否安全?

Is it safe to read values from a thread without synchronize?

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

假设我从一个线程(没有 TThread.Synchronize)的 TMemo/TEdit 控件逐行读取(或者它的标题 属性), 但也确定 TMemo/TEdit 控件已被禁用 and/or 它的只读标志已被启用。

安全吗?

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

您可能会认为可以使用 SendMessage 传递 WM_GETTEXTLENGTH/WM_GETTEXT 来安排 window 过程在主线程上执行。但这受制于恶劣的竞争条件。您需要 window 句柄才能使用 SendMessage,但在工作线程上访问 Handle 属性 不是线程安全的。这必须在主线程上完成,否则 VCL window 重新创建会导致 window 由您的工作线程创建。而GUI windows 必须由主线程创建。