在没有同步的情况下从线程读取值是否安全?
Is it safe to read values from a thread without synchronize?
我想知道从主线程外的 VCL 控件中 读取 值是否安全。
假设我从一个线程(没有 TThread.Synchronize
)的 TMemo/TEdit
控件逐行读取(或者它的标题 属性), 但也确定 TMemo/TEdit
控件已被禁用 and/or 它的只读标志已被启用。
安全吗?
不,这不安全。通过调用 window 过程(使用 Perform
方法),传递 WM_GETTEXTLENGTH
和 WM_GETTEXT
来读取备忘录和编辑控件的内容。 Win32 要求此类代码在创建 window 的线程上执行,在本例中为主线程。因此,当您从工作线程读取 Text
属性 时,您违反了该规则,因为您在工作线程上调用了 Perform
,然后在工作线程上执行了 window 过程线程错误。
您可能会认为可以使用 SendMessage
传递 WM_GETTEXTLENGTH/WM_GETTEXT
来安排 window 过程在主线程上执行。但这受制于恶劣的竞争条件。您需要 window 句柄才能使用 SendMessage
,但在工作线程上访问 Handle
属性 不是线程安全的。这必须在主线程上完成,否则 VCL window 重新创建会导致 window 由您的工作线程创建。而GUI windows 必须由主线程创建。
我想知道从主线程外的 VCL 控件中 读取 值是否安全。
假设我从一个线程(没有 TThread.Synchronize
)的 TMemo/TEdit
控件逐行读取(或者它的标题 属性), 但也确定 TMemo/TEdit
控件已被禁用 and/or 它的只读标志已被启用。
安全吗?
不,这不安全。通过调用 window 过程(使用 Perform
方法),传递 WM_GETTEXTLENGTH
和 WM_GETTEXT
来读取备忘录和编辑控件的内容。 Win32 要求此类代码在创建 window 的线程上执行,在本例中为主线程。因此,当您从工作线程读取 Text
属性 时,您违反了该规则,因为您在工作线程上调用了 Perform
,然后在工作线程上执行了 window 过程线程错误。
您可能会认为可以使用 SendMessage
传递 WM_GETTEXTLENGTH/WM_GETTEXT
来安排 window 过程在主线程上执行。但这受制于恶劣的竞争条件。您需要 window 句柄才能使用 SendMessage
,但在工作线程上访问 Handle
属性 不是线程安全的。这必须在主线程上完成,否则 VCL window 重新创建会导致 window 由您的工作线程创建。而GUI windows 必须由主线程创建。