Is it possible to set the CultureInfo for an .NET application or just a thread?
Asked Answered
G

4

28

I've an application written in C# which has no GUI or UI, but instead writes files that are parsed by another application (in XML and others).

I have a customer whose CultureInfo has the NumberDecimalSeparator set to a comma, which causes parsing errors with floating point numbers (PI would end up as 3,1415).

I'd like a way to set the CultureInfo globally within the application, for all threads. I've tried:

  1. The (apparently) customary approach of setting CurrentThread.CurrentCulture as the first line in Main() but it appears to get reset.
  2. A variation/expansion on http://www.codeproject.com/KB/cs/Change_App_Culture.aspx
  3. Do the same (#1) on the explicitly created threads in the application.

And changing to use explicit formatting is not an option (150K+ lines, most written by former employees).

[Edit] The application binds to a socket and handles requests from dedicated clients. Depending on the request type it spawns different handler classes.

Sorry, when I first posted I should have clarified in #1 that (I though) I had done this in all of the handlers that were explicitly spawned, too.

It turns out that I missed the thread/handler that was causing the problem. So the application is working properly now, but the question remains about if the culture can be set on all threads.

If it could iterate over all threads, it would solve the issue, too. So:

How can I get all Thread objects (not ProcessThread) in the current process?

Galliwasp answered 10/2, 2010 at 4:52 Comment(0)
W
18

Unfortunately, every new thread starts with system locale information, even if it's started from a thread that's had its locale changed to something else.

This was a huge gotcha I ran into in one of our apps when using a BackgroundWorker to load a file.

The approach I've used successfully is to set the locale on the startup thread, and then use a thread factory to create threads with the "application locale." For BackgroundWorkers you can use either a factory or a derived class, as Thread is sealed while BackgroundWorker is not.

Wiese answered 11/2, 2010 at 20:42 Comment(1)
Helps only if you're in control of thread creation. Sometimes you have to deal with threads created by .NET. One should never forget the holy line System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("EN-US");Klingensmith
S
43

In .NET 4.5 you can use CultureInfo.DefaultThreadCurrentCulture

Science answered 2/7, 2012 at 12:46 Comment(0)
W
18

Unfortunately, every new thread starts with system locale information, even if it's started from a thread that's had its locale changed to something else.

This was a huge gotcha I ran into in one of our apps when using a BackgroundWorker to load a file.

The approach I've used successfully is to set the locale on the startup thread, and then use a thread factory to create threads with the "application locale." For BackgroundWorkers you can use either a factory or a derived class, as Thread is sealed while BackgroundWorker is not.

Wiese answered 11/2, 2010 at 20:42 Comment(1)
Helps only if you're in control of thread creation. Sometimes you have to deal with threads created by .NET. One should never forget the holy line System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("EN-US");Klingensmith
T
7

I don't think you can set the culture for the whole application, but you can set the culture explicilty whenever you create a thread:

using System;
using System.Globalization;
using System.Threading;

class Program {

    static void thread_test() {
        Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName);
    }

    public static void Main(params string[] args) {
        Thread t = new Thread(thread_test);
        t.CurrentCulture = new CultureInfo("it-it");
        t.Start();
        t.Join();
    }
}
Tudela answered 10/2, 2010 at 8:40 Comment(0)
M
5

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

Marrano answered 1/11, 2010 at 8:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.