Trouble with threads and cultures

Here’s something that bit me today. A few days ago, a Windows Service I built was redeployed to another machine. Most operations went on just fine, but some didn’t. And as always: ‘it worked on my machine’. As it had also worked in testing and on the previous production server. After some digging, we found that the regional settings for the service account on this machine were not what they were on the other servers. Yes, I know, don’t depend on regional settings, but there was some legacy code (hah..it’s not my fault) and it had never created issues before.

So, easy enough, we set the thread for the service to the required culture, like so:

System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(“nl-NL”);

Unfortunately, it didn’t have the desired effect. Nothing changed. As it turns out, you have to set the culture on every thread running. See the sample below:

using System;

using System.Globalization;

using System.Threading;

 

namespace RegionalTime

{

    class ClassDemo

    {

        public static void TimeNow()

        {

            Console.WriteLine(“Date setting: {0} ({1})”,

                DateTime.Now.ToLongDateString(),

                Thread.CurrentThread.CurrentCulture.DisplayName);

        }

 

        public delegate void TimeNowDelegate();

 

        [STAThread]

        static void Main(string[] args)

        {

            // Look at current regional settings

            TimeNow();

 

            // Switch to French

            Thread.CurrentThread.CurrentCulture = new CultureInfo(“fr-FR”);

            TimeNow();

 

            // Switch to US

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

            TimeNow();

 

            // Now through a delegate on a different thread.

            TimeNowDelegate methodDelegate = new TimeNowDelegate(TimeNow);

 

            IAsyncResult result = methodDelegate.BeginInvoke(null, null);

 

            while (!result.IsCompleted)

            {

                Thread.Sleep(500);

            }

 

        }

    }

}

As you will see, from running this code, the call through the delegate uses the regional settings from the active user.

Date setting: woensdag 11 april 2007 (Dutch (Netherlands))
Date setting: mercredi 11 avril 2007 (French (France))
Date setting: Wednesday, April 11, 2007 (English (United States))
Date setting: woensdag 11 april 2007 (Dutch (Netherlands))
Press any key to continue . . .

There seems to be no way to specify one culture for the entire AppDomain (note: I’m not talking about ASP.NET here, this was a multithreaded Windows Service). If any thinks or better yet, knows, that this is possible, let me know. I am always eager to learn.