Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define culture for entire appdomain

I'm creating a windows service that runs multiple threads. Can I set the culture of my entire appDomain, instead of setting it to each thread separately?

like image 967
Nissim Avatar asked Sep 13 '10 07:09

Nissim


2 Answers

For 4.5 default app domain cultures could be set via CultureInfo class:

  • DefaultThreadCurrentCulture
  • DefaultThreadCurrentUICulture
like image 158
wałdis iljuczonok Avatar answered Sep 20 '22 13:09

wałdis iljuczonok


This is not possible. Threads get their default culture when Windows creates the thread, initialized from the system default locale as configured in Control Panel + Region and Language. The relevant Win32 API functions are Get/SetThreadLocale().

There is no mechanism in the CLR to imbue a thread with another default. A common scenario for a thread is to start life created by unmanaged code and run lots of that unmanaged code, occasionally making a callback into managed code. That managed code will run with the Thread.CurrentCulture set to the culture selected by the unmanaged code. Or the Windows default if the unmanaged code didn't call SetThreadLocale(). Having the CLR change it would cause undiagnosable failure in the unmanaged code.

Of course you can override it explicitly but that's difficult to get right. The subtle formatting errors are easy enough to see, it gets hard when you use, say, data structures that implicitly rely on the collating orders of string. A SortedList suddenly cannot find an element back in the list that is actually present. Controlling it is hard too, lots of little threadpool thread callbacks throughout the .NET framework.

Don't mess around with this to avoid falling into traps like these, either rely on the system default or apply the CultureInfo explicitly.


UPDATE: as noted by Thomas, a solution will be available in .NET 4.5, it has a new property for the CultureInfo class to set the appdomain's default culture. MSDN docs are here. The exact interaction with unmanaged threads that enter managed code isn't very clear from the documentation, be sure to check this if you ever allow native code to make callbacks, such as through pinvoke, Marshal.GetFunctionPointerForDelegate() or a COM object's event.


UPDATE2: this was changed again in .NET 4.6, culture now flows from one thread to another so the nastiest failure modes are taken care of. Read the details about it in the MSDN article for CultureInfo.CurrentCulture. You have to explicitly target 4.6 to get the benefit.

like image 21
Hans Passant Avatar answered Sep 19 '22 13:09

Hans Passant