【问题标题】:Should VCL Components Use Thread-Safe FunctionsVCL 组件是否应该使用线程安全函数
【发布时间】:2018-01-13 15:19:14
【问题描述】:

我正在开发一个仅限 VCL 的自定义日期编辑组件。我计划使用 System.SysUtils.FormatDateTime 函数将 TDate 转换为字符串。 FormatDateTime 有两个版本——一个是线程安全的,另一个不是。由于 VCL 不是线程安全的,我应该更喜欢线程安全的版本还是非线程安全的版本可以使用?

【问题讨论】:

  • 可视化组件不是线程安全的,所以使用哪一个都没有关系。该组件不能从线程中使用。
  • 重载不仅仅是线程安全。它更多的是在不影响全局设置的情况下自定义格式设置。如果您的组件需要将日期/时间转换为特定格式的字符串,请使用重载,而不考虑线程。

标签: multithreading delphi thread-safety custom-component


【解决方案1】:

只要调用者是主线程,你是否选择函数的非线程安全变体都没关系。在这种情况下似乎是(如果您没有在组件内部创建一个工作线程来调用该函数,并且您遵守不会在任何工作线程中使用控件的规则,您将放心吧)。

但还有更多需要考虑。如果您有最新的 Delphi 版本并启用 UpdateFormatSettings 属性,则当用户修改其系统上的本地设置时,FormatDateTime 函数的非线程安全重载中使用的全局声明格式设置变量将得到更新。我不能说关于控制通知的任何内容(因此您可以更新输出),因为我现在手头只有 D2009,这些更改已在以后添加。

【讨论】:

    【解决方案2】:

    tl;dr 使用线程安全版本

    如果您使用非线程安全版本,那么您将限制组件的任何使用者不要在线程中使用相同的非线程安全版本。

    无论如何,这都不是不合理的限制。使用非线程安全版本只有在从不远离主线程的程序中才真正可行。因此,一个程序必须首先打破规则,您的组件才会被影响。

    话虽如此,组件作者原则上应该避免对消费程序做出任何假设。所以最好的做法是调用线程安全版本。那么就无法进行辩论。您的程序不会涉及这些语言环境全局变量的任何线程安全问题。

    【讨论】:

    • 可能会有争论 :) 为什么要从非主线程调用可视控制方法?我会接受控件使用的线程安全接口,而不是从工作线程中调用方法或使用可视控件的属性访问器。我永远不会将我的视觉控件设计为线程安全的。不调用任何方法只是消费者的责任。附:您还可以补充说,您应该(很可能)听取区域设置更改(如果您想在控件的输出中反映此类更改)。
    • @Victoria 应用程序中的任何代码都可以调用 RTL 函数。它不必是组件的方法。
    • 对不起,我不明白你的意思。恕我直言,存在非线程安全FormatDateTime 重载只是为了向后兼容。对全局格式设置变量的访问应该被设计为线程安全是另一点。我的观点是,从视觉控制你不必害怕使用它们中的任何一个。如果您想拥有可自定义的格式,请使用线程安全重载(如果您决定这样做,可以选择收听WM_SETTINGCHANGE 消息以反映用户设置)。
    • 嗯,应用程序中的任何代码都可以调用任何 RTL 函数是一个美好的愿望,但您只需要在 Delphi 中小心。但不是在这里。如果他们试图从工作线程调用可视控件的方法,这只是开发人员的错。
    • 对于该格式,结果取决于作为语言环境一部分的短月份名称。所以没有什么不同。调用接受格式设置记录的版本真的不难。
    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多