注意:过时的材料,请务必阅读底部的更新以了解 .NET 4.6 中的更改
是的,这是一个常见的请求,但无法实现。 Windows 始终将操作系统线程初始化为系统默认 LCID,该 LCID 在控制面板的区域和语言选项小程序中配置。只要您自己创建线程,您就可以覆盖它。但这对于线程池线程和可能由运行进程的某种非托管代码(如 COM 服务器)创建的线程来说并不实用。
后一种情况就是问题所在。 .NET 在由非托管代码创建的线程上运行托管代码没有任何问题。但它无法对线程的初始化方式做任何事情。对于 CurrentUICulture 来说是这样,但对于 Thread.SetApartmentState() 这样更晦涩难懂的东西也是如此。不要低估这样的线程在您的程序中运行代码的可能性,Microsoft 编写的 COM 服务器非常适合线程。
您必须仔细检查您的代码,并找到可能在您未创建的线程上运行的任何代码。任何事件处理程序都是可疑的,任何具有回调的 BeginXxx() 方法也是如此。 BackgroundWorker 绝对是较小的问题。
不覆盖线程的区域性会产生very微妙且难以诊断 bugz。一个很好的例子是一个以字符串为键的 SortedList。当使用错误的区域性运行时,它会随机无法找到列表中实际存在的元素。由于列表在具有不同排序规则的另一种文化中不再排序所致。
如果我成功地吓到了你,那么我就传达了我的信息。这发生在我身上,当时我正在调试一个在丹麦机器上行为异常的大型程序的问题。我们没有丹麦语本地化,因此强制用户界面以英语运行。工作线程使用以字符串作为键的红黑树。当被要求对付奥德瓦克斯时,它随机失败。我花了一周时间。
更新:此问题已在 .NET 4.5 中得到解决。 CultureInfo 类现在有一个默认线程当前文化 http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.defaultthreadcurrentculture%28v=vs.110%29.aspx和 DefaultThreadCurrentUICulture。设置后,它将用于初始化任何托管线程的区域性,而不是默认的 Windows 系统区域性。我还不清楚它如何与由本机代码启动并输入托管代码的线程交互。
更新:这个问题在.NET 4.6中有更彻底的解决方案。现在,文化会自动流动,这是理想的行为。 MSDN 文章为CultureInfo.CurrentCulture() https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.currentculture%28v=vs.110%29.aspx谈论它。提供的信息仍然令人困惑,实验上它似乎也流向 Thread 对象,而不仅仅是任务或线程池线程,并且不使用 DefaultThreadCurrentCulture。进两步,退一步,建议进行测试。