C# 如何设置主线程的值';是否从.NET Core 3.1中的子线程创建s CultureInfo.CurrentUICulture? 背景:

C# 如何设置主线程的值';是否从.NET Core 3.1中的子线程创建s CultureInfo.CurrentUICulture? 背景:,c#,async-await,cultureinfo,.net-core-3.1,currentuiculture,C#,Async Await,Cultureinfo,.net Core 3.1,Currentuiculture,我有一个async await函数,它从外部源获取语言和语言环境参数,这将用于设置CurrentUICulture 我的web应用程序是使用C语言在.NETCore3.1中构建的# 问题: CurrentUICulture仅在子方法的上下文中设置,一旦超出此范围,CurrentUICulture不会反映更改的值 我的困境: 我知道总是建议从主线程(而不是从子线程)设置CurrentUICulture的值,但我正在处理一个现有代码,其中对thread.CurrentThread.CurrentUI

我有一个async await函数,它从外部源获取语言和语言环境参数,这将用于设置CurrentUICulture

我的web应用程序是使用C语言在.NETCore3.1中构建的#

问题: CurrentUICulture仅在子方法的上下文中设置,一旦超出此范围,CurrentUICulture不会反映更改的值

我的困境: 我知道总是建议从主线程(而不是从子线程)设置CurrentUICulture的值,但我正在处理一个现有代码,其中对thread.CurrentThread.CurrentUICulture有太多的依赖性,我很难在不同的地方进行更改

片段: 实际产量: (假设外部服务返回的值为“pt BR”[葡萄牙-巴西])

Main-Thread:当前的UI文化是en-US
子线程:UI区域性更改为pt BR
主线:更改后的UI文化是en US
期望输出:
Main-Thread:当前的UI文化是en-US
子线程:UI区域性更改为pt BR
主线:更改后的UI区域性为pt BR

解决该问题的任何线索都是非常值得注意的。

我假设您不希望您的主线程在其文化设置之前做任何其他事情。对我来说,这似乎是一个合理的假设

在这种情况下,您可以只阻塞主线程:

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.
}
如果这是一个UI应用程序,那么您可以在后台线程上运行异步代码:

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.
}

不要设置线程区域性。将其显式传递给接受
IFormatProvider
的任何格式化或解析方法。没有理由将父线程区域性或子线程区域性设置为自身操作
线程。从
任务开始操作CurrentThread
是一个坏主意,因为您无法保证
任务
将在哪个线程上结束。这是局部问题的全局解决方案。如果因为线程操纵区域性而必须将代码固定到线程,那么就通过显式创建和管理
thread
s来执行。这当然很尴尬,但这就是线程关联的结果。为什么不让子任务将区域性字符串返回到主线程,并让主线程设置区域性?@HereticMonkey-这并不像我的代码片段中所看到的那样直截了当。实际的代码太复杂了。这个想法不仅不好,而且“不可行”。不要使用
任务
s或者不要使用
线程.CurrentCulture
,这是基本要点。从理论上讲,可以使用自定义调度器和随任务一起传递的自定义上下文来执行任务,以确保捕获区域性,但这些解决方案甚至比修复代码更费事,而且最终的可维护性肯定更低。注意,线程之间没有“父”或“子”的概念;只有任务有类似的功能(即使在那里也很少使用)。
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.
}