How can I change the CurrentCulture of the entire process (not just current thread) in .Net?

44,700

Solution 1

You'll have to change the operating system locale if you want to do that. For what reason do you want BackgroundWorkers to run in en-US?

You should have your business layer running in an invariant culture, and only have a specific culture for the end user's UI.

If you are using the BackgroundWorker component, and have to do this you could try something like this in the DoWork method:

// In DoWork
System.Globalization.CultureInfo before = System.Threading.Thread.CurrentThread.CurrentCulture;
try

{
    System.Threading.Thread.CurrentThread.CurrentCulture = 
        new System.Globalization.CultureInfo("en-US");
 // Proceed with specific code
}

finally
{
    System.Threading.Thread.CurrentThread.CurrentUICulture = before;
}

Solution 2

With 4.0, you will need to manage this yourself by setting the culture for each thread. But with 4.5, you can define a culture for the appdomain and that is the preferred way to handle this. The relevant apis are CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture.

Solution 3

We use helper class for BackgroudWorker like this:

public static class BackgroundWorkerHelper
{
public static void RunInBackground(Action doWorkAction, Action completedAction, CultureInfo cultureInfo)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (_, args) =>
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
            System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
            doWorkAction.Invoke();
        };
        worker.RunWorkerCompleted += (_, args) =>
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
            System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
            completedAction.Invoke();
        };

        worker.RunWorkerAsync();
    }
}

Example usage:

BackgroundWorkerHelper.RunInBackground(() => { Work(); }, () => { AfterWork(); },Thread.CurrentThread.CurrentCulture);

Solution 4

Use this:

worker.RunWorkerAsync(Thread.CurrentThread.CurrentCulture.LCID);//Pass the LCID as argument

after on do work make this:

Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(int.Parse(e.Argument.ToString()));
Share:
44,700
Assaf Lavie
Author by

Assaf Lavie

assaflavie.com

Updated on January 08, 2020

Comments

  • Assaf Lavie
    Assaf Lavie over 4 years

    I have a situation where I need to set my process' locale to en-US.

    I know how to do this for the current thread:

    System.Threading.Thread.CurrentThread.CurrentCulture = 
         System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
    

    But my application uses BackgroundWorkers to do some processing, and the locale for these worker threads seems not to be affected by the above change to their spawning main-thread.

    So how can I set the locale for all the threads in my application without setting it in each one manually?

  • Fredrik Mörk
    Fredrik Mörk over 14 years
    The background worker may very well be running in the UI layer (as a BackgroundWorker component on a Form for instance)
  • RichardOD
    RichardOD over 14 years
    @Fredrik- Yes (especially if it is the Background Worker component), but you don't update the UI on the background worker thread. At least you don't if you are using it properly.
  • Assaf Lavie
    Assaf Lavie over 14 years
    The background worker does double.Parse(string) on some input, which breaks for certain locales that have weird decimal point representations. So, I still need to know how to set the locale for the entire process. Are you saying this isn't possible?
  • RichardOD
    RichardOD over 14 years
    Assaf- can you post a code sample. Do none of my suggestions work for you?
  • Assaf Lavie
    Assaf Lavie over 14 years
    I ended up inheriting from BW and setting the CurrentCulture before every thread function...
  • RichardOD
    RichardOD over 14 years
    Assaf- sounds like a good approach- especially if you want to reuse the functionality in other places.
  • AlwaysLearning
    AlwaysLearning over 8 years
    +1 for using a culture identifier instead of a culture name. This is necessary to separate Spanish - Spain from Spanish - Spain, for example, where 0x0C0A uses international sort order and 0x040A uses traditional sort order. REF: CultureInfo Class
  • Shimmy Weitzhandler
    Shimmy Weitzhandler over 4 years
    It's important that this is done before any service registrations etc. otherwise they might be created with the old culture.