.NET中新线程文化与主线程一致不符合预期,是否为Bug?
你观察到的现象完全符合.NET的线程文化继承规则,不属于Bug,具体原因如下:
CultureInfo.DefaultThreadCurrentCulture的优先级逻辑
微软文档中"新线程使用系统默认Locale"的描述,仅适用于CultureInfo.DefaultThreadCurrentCulture(以及对应的DefaultThreadCurrentUICulture)为null的场景。一旦这个属性被设置(包括间接触发的设置),新创建的线程(含ThreadPool线程)会优先使用该属性指定的文化,而非系统默认值。主线程文化修改的间接影响
在.NET Framework环境下,当你修改主线程的CurrentCulture或CurrentUICulture时,DefaultThreadCurrentCulture和DefaultThreadCurrentUICulture会被自动同步为你修改后的文化值。从你的运行结果能看到Default Thread Culture is ja-JP,说明该属性已不为null,因此新线程自然会采用ja-JP文化,而非系统默认。.NET Core/.NET 5+的默认规则
如果你在较新的.NET平台运行代码,默认行为是新线程直接继承创建它的线程的文化设置,无需依赖DefaultThreadCurrentCulture。你的主线程已将文化改为ja-JP,后续的Worker线程和ThreadPool线程自然会继承这个配置。
从你的运行结果来看,所有线程的CurrentCulture均为ja-JP,且DefaultThreadCurrentCulture显示为ja-JP,完全匹配上述规则,属于正常的预期行为,无需向.NET团队上报Bug。
你的示例代码
static Random rng = new Random(); static void DisplayThreadInfo() { Console.WriteLine($"Thread Name:{Thread.CurrentThread.Name}"); Console.WriteLine($"Current Culture:{Thread.CurrentThread.CurrentCulture.Name}"); Console.WriteLine($"Current UI Culture:{Thread.CurrentThread.CurrentUICulture.Name}"); Console.WriteLine($"Default Thread Culture is {CultureInfo.DefaultThreadCurrentCulture}"); // If this is null, current system culture used as default culture for new threads, } static void DisplaySomeCultureDependentValues() { // Show three random number as currency for (int i = 0; i < 3; i++) { Console.WriteLine("{0}th Value:{1:C2}", i, rng.NextDouble() * 10000); } } static void ThreadProc() { DisplayThreadInfo(); DisplaySomeCultureDependentValues(); } private static void Main(string[] args) { if (CultureInfo.CurrentCulture.Name != "ja-JP") { CultureInfo.CurrentCulture = new CultureInfo("ja-JP"); CultureInfo.CurrentUICulture = new CultureInfo("ja-JP"); } else { CultureInfo.CurrentCulture = new CultureInfo("ar-SA"); CultureInfo.CurrentUICulture = new CultureInfo("ar-SA"); } ThreadProc(); // Create a new thread and run ThreadProc with it Thread thread = new Thread(ThreadProc); thread.Name = "Worker Thread"; thread.Start(); // Use Thread Pool instead of creation of thread ThreadPool.QueueUserWorkItem((obj) => ThreadProc()); }
运行结果

内容的提问来源于stack exchange,提问作者Mehdi Mowlavi

