Skip to content

Thread-safe Format

The Format function isn’t thread-safe unless you use the overload which takes a FormatSettings argument (because the FormatSettings-less version uses global variables). I use it to compose error messages in a thread I’m writing, and I want to use the same FormatSettings as the user would normally see in a GUI app. So here’s what I did. I added a TFormatSettings field to my thread class:

  TMyThread = class(TThread)
  private
    FFormatSettings: TFormatSettings;
  protected
    procedure Execute; override;
  end;

Then I set it at the start of the Execute method:

procedure TMyThread.Execute;
begin
    GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FFormatSettings);
end;

This seems to work well.
Update: On further thought I may be able to roll this all into the thread itself and not deal with it at creation time. But the important point is how to use GetThreadLocale and GetLocaleFormatSettings, which took some digging to find.
Update 2: I significantly changed how this works based on Yorai’s comments in Feedback.

{ 5 } Comments

  1. F1 is your friend | August 25, 2005 at 6:45 pm | Permalink

    From "Format Function" Delphi 7 Help file:

    "The first form of Format is not thread-safe, because it uses localization information contained in global variables. The second form of Format, which is thread-safe, (…)"

    "To populate FormatSettings with a set of default locale values, call GetLocaleFormatSettings."

    :)

    Regards!

    F.D.Castel

  2. Craig Stuntz | August 25, 2005 at 7:25 pm | Permalink

    Yes, FD, I did read that, but there is no code example and it wasn’t obvious to me where to get the LCID argument.

    Believe it or not I do use Help.

  3. Yorai Aminov | August 26, 2005 at 3:02 am | Permalink

    I’m having second thoughts about GetThreadLocale - lots of things can go wrong there (some are described at http://blogs.msdn.com/michkap/archive/2005/08/22/454360.aspx). To support the user’s settings, use LOCALE_USER_DEFAULT. If you want the system locale (since it seems you’re running this in a service), use LOCALE_SYSTEM_DEFAULT.

    - Yorai

  4. Craig Stuntz | August 26, 2005 at 8:25 am | Permalink

    Thanks very much, Yorai! That’s excellent feedback. I’ll update the example with your suggestion. I wish this sort of thing were in the documentation.

  5. Ralf | August 26, 2005 at 3:55 pm | Permalink

    Is there a QC about that issue?

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 1846 access attempts in the last 7 days.

Close