Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Threading, CultureInfo .net , TPL, PLINQ

It is not possible to set an entire .net application to another culture other than the user profile-culture in .net. The appropriate way to control cultureinfo seems to be using the dedicated methods on objects such as DateTime.

However, when dealing with massive amounts of legacy code (not all code under your control) this is not possible to achieve. Therefor one can for example create a subclass/wrapper to Thread och Threadpool and set the required cultureinfo before the delegate is executed, or the delegate itself could be required to contain a set of the culture. (hard to validate and prone to misstakes...)

Looking at TPL, more specifically PLINQ, however I find it hard, if not impossible, to change culture settings in a centralized way.

Any suggestions that deals withoverriding thread/application-cultureinfo in legacy code?

Thanks!

like image 207
Jens Avatar asked Dec 09 '10 14:12

Jens


1 Answers

When a thread is started, its culture is initially determined by using GetUserDefaultLCID from the Windows API. I found no way (I assume there is no way) to override this behavior. Only thing you can do is to set the thread culture afterwards.

I wrote an extension. For that:

public static class ParallelQueryCultureExtensions
{
    public static ParallelQuery<TSource> SetCulture<TSource>(this ParallelQuery<TSource> source, CultureInfo cultureInfo)
    {
        SetCulture(cultureInfo);
        return source
            .Select(
                item =>
                    {
                        SetCulture(cultureInfo);
                        return item;
                    });
    }

    private static void SetCulture(CultureInfo cultureInfo) {
        if (Thread.CurrentThread.CurrentCulture != cultureInfo) {
            Thread.CurrentThread.CurrentCulture = cultureInfo;
        }
    }
} 

So if you use it just after splitting up the original source using .AsParallel() you will get what you want.

    CultureInfo kaCulture = CultureInfo.GetCultureInfo("ka-Ge");

    int[] array = new int[100];
    Random random =  new Random();
    int index =0;
    Array.ForEach(array, i => { array[index++] = index;});

    array
        .AsParallel()
        .SetCulture(kaCulture)
        .ForAll(
            i =>
                {
                    Thread.Sleep(random.Next(5));
                    Console.WriteLine("Thread-{0} \t Culture-'{1}' \t Element-{2}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.CurrentCulture, i);
                });

    Console.WriteLine("Press any key to quit");
    Console.ReadKey(); 
like image 128
George Mamaladze Avatar answered Oct 09 '22 20:10

George Mamaladze