简体   繁体   中英

How to set the value of main thread's CultureInfo.CurrentUICulture from a child thread in .NET Core 3.1?

Background:

I have an async await function that gets a language and locale parameters from an external source and this will be used to set to the CurrentUICulture.

My web application is built in .NET Core 3.1 using C#

Problem:

The CurrentUICulture is set only in the context of Child method and once it goes out of this scope, CurrentUICulture doesn't reflect the changed value.

My Predicament:

I know it is always recommended to set the value of CurrentUICulture from main thread (and not from a child thread), but I am working on an existing code where there is too much of dependency on Thread.CurrentThread.CurrentUICulture and it is practically difficult for me to change at various places.

Snippet:

public class Example
{
   public static async Task Main()
   {
      Console.WriteLine("Main Thread: Current UI culture is {0}",
                        Thread.CurrentThread.CurrentUICulture.Name);
     
      await Child();      

      Console.WriteLine("Main Thread: UI culture after change is {0}",
                        Thread.CurrentThread.CurrentUICulture.Name);
   }
   public static async Task Child()
   {
      //get the culture text from an external service (assume this will return "pt-BR")
      var cultureText = await externalService.GetCultureAsync();

      //set the culture
      Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureText);
      Console.WriteLine("Child Thread: UI culture changed to {0}",
                        Thread.CurrentThread.CurrentUICulture.Name);
   }
}

Actual Output:

(Assume the value returned by external service is "pt-BR" [Portugese Brazil])

Main Thread: Current UI culture is en-US
Child Thread: UI culture changed to pt-BR
Main Thread: UI culture after change is en-US

Desired Output:

Main Thread: Current UI culture is en-US
Child Thread: UI culture changed to pt-BR
Main Thread: UI culture after change is pt-BR

Any leads to solve the issue would be highly appreciable.

I assume you don't want your main thread to do anything else until it has its culture set. That seems like a reasonable assumption to me.

In that case, you can just block the main thread:

public static async Task Main()
{
  // Nothing should use await before this line.
  var cultureText = externalService.GetCultureAsync().GetAwaiter().GetResult();
  Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureText);

  // Other code that can use await.
}

If this is a UI app, then you can run the asynchronous code on a background thread:

public static async Task Main()
{
  // Nothing should use await before this line.
  var cultureText = Task.Run(() => externalService.GetCultureAsync()).GetAwaiter().GetResult();
  Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureText);

  // Other code that can use await.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM