C# BackgroundWorker的文化

标签 c# multithreading culture

我想为我的整个应用程序设置文化。我尝试了以下操作:

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(wantedCulture);
Application.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture);

它适用于当前线程,但稍后我创建并启动了一个后台工作线程。当我创建工作人员时,当前线程使用 wantedCulture 执行,但工作线程将使用我计算机的文化运行。

有什么想法可以为整个应用程序设置文化吗?

最佳答案

注意:过时的 Material ,请务必阅读底部的更新以了解 .NET 4.6 中的更改

是的,这是一个常见的请求,但它不可用。 Windows 始终将操作系统线程初始化为系统默认 LCID,在控制面板的区域和语言选项小程序中配置。只要您自己创建线程,就可以覆盖它。但这对于线程池线程和可能由运行进程的某种非托管代码(如 COM 服务器)创建的线程来说并不实用。

后一种情况就是问题所在。 .NET 在非托管代码创建的线程上运行托管代码没有问题。但是它不能对线程的初始化方式做任何事情。这对于 CurrentUICulture 是正确的,但对于像 Thread.SetApartmentState() 这样的更晦涩的东西也是如此。不要低估这样的线程在您的程序中运行代码的可能性,Microsoft 编写的 COM 服务器非常适合线程。

您将不得不仔细梳理您的代码,并找出任何可能在您未创建的线程上运行的代码。任何事件处理程序都是可疑的,任何具有回调的 BeginXxx() 方法也是如此。 BackgroundWorker 绝对是较小的问题。

不覆盖线程的文化会产生非常微妙且难以诊断的错误。一个很好的例子是一个以字符串为键的 SortedList。当以错误的文化运行时,它会随机地找不到列表中实际存在的元素。由于在具有不同排序规则的另一种文化中不再对列表进行排序。

如果我成功地吓到你了,那么我就传达了我的信息。这发生在我身上,调试一个非常大的程序在丹麦机器上运行不正常的问题。我们没有丹麦语本地化版本,因此强制 UI 以英语运行。工作线程使用以字符串为键的红黑树。当要求处理 Åårdvårks 时,它随机失败。花了我一个星期。


更新:此问题已在 .NET 4.5 中得到解决。 CultureInfo 类现在有一个 DefaultThreadCurrentCulture和 DefaultThreadCurrentUICulture。设置后,它将用于初始化任何托管线程的文化,而不是默认的 Windows 系统文化。我还不清楚它究竟如何与由 native 代码启动并进入托管代码的线程交互。


更新:此问题在 .NET 4.6 中有更彻底的解决方案。文化现在自动流动,这是理想的行为。 CultureInfo.CurrentCulture() 的 MSDN 文章谈论它。提供的信息仍然令人困惑,实验上它似乎也流向 Thread 对象,而不仅仅是 Task 或线程池线程,并且未使用 DefaultThreadCurrentCulture。进两步,退一步,建议测试。

关于C# BackgroundWorker的文化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2385942/

相关文章:

c# - Clay and CaSTLe 温莎 2.5

c# - 通过 linq 加入数据表

c# - 2 WCF 服务和 c# 线程

razor - 如何在 ServiceStack 中正确本地化 Razor View

c# - 显示箭头的 MS 柱形图

c# - 在 C# (.NET 3.5) 中反序列化 xml 时是否可以设置默认值?

c++ - QCustomPlot 海量数据绘图

c# - MSBuild BuildInParallel,无法运行的自定义任务生成过程

c# - Kentico Cultures 导航后无法正常工作

c# - 如何在不改变文化的情况下更改 c# winform 应用程序的资源文件?