Search code examples
c#asp.net-mvcmultithreadingglobalizationcurrentculture

How to correctly inherit thread culture in a parallel block?


I'm using automatic globalization on an ASP MVC website. It works fine until it reached a parallel block:

public ActionResult Index() 
{
     // Thread.CurrentThread.CurrentCulture is automatically set to "fr-FR"
     // according to the requested "Accept-Language" header

     Parallel.Foreach(ids, id => {
        // Not every thread in this block has the correct culture. 
        // Some of them still have the default culture "en-GB"
     }) ; 

     return View()
}

What is the best way to make the parallel block inherit the culture? apart from this solution:

public ActionResult Index() 
{
     var currentCulture = Thread.CurrentThread.CurrentCulture  ;

     Parallel.Foreach(ids, id => {
         // I don't know if it's threadsafe or not. 
         Thread.CurrentThread.CurrentCulture = currentCulture ; 

     }) ; 

     return View()
}

Solution

  • You can create your own Parallel.ForEach handling thread culture :

    public static class ParallelInheritCulture
    {
        public static ParallelLoopResult ForEach<T>(IEnumerable<T> source, Action<T> body)
        {
            var parentThreadCulture = Thread.CurrentThread.CurrentCulture; 
            var parentThreadUICulture = Thread.CurrentThread.CurrentUICulture; 
    
            return Parallel.ForEach(source, e =>
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture; 
                var currentUICulture = Thread.CurrentThread.CurrentUICulture; 
    
                try
                {
                    Thread.CurrentThread.CurrentCulture = parentThreadCulture;
                    Thread.CurrentThread.CurrentUICulture = parentThreadUICulture;
    
                    body(e); 
                }
                finally
                {
                    Thread.CurrentThread.CurrentCulture = currentCulture;
                    Thread.CurrentThread.CurrentUICulture = currentUICulture;
                }
            }); 
        }
    }
    

    Then:

     ParallelInheritCulture.Foreach(ids, id => {
        // Whatever
    
     }) ;