C#BackgroundWorker的文化

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

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

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

为整个应用程序设置文化的任何想法?

注意:注明日期的材料,请务必阅读底部的更新以了解.NET 4.6中的更改

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

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

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

不重写线程的文化可以产生非常微妙和难以诊断的bugz。 一个很好的例子是一个键入字符串的SortedList。 当使用错误的文化运行时,它将无法找到列表中实际存在的元素。 由于列表不再在具有不同整理规则的另一种文化中进行排序而导致。

如果我设法吓到你,那么我就会传达我的信息。 这件事发生在我身上,调试了一个在丹麦机器上行为exception的大型程序的问题。 我们没有丹麦语本地化,并迫使用户界面以英语运行。 工作线程使用了一个以字符串为键的红黑树。 当被要求与Åårdvårks打交道时,它失败了。 花了我一个星期的时间。


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


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

我的解决方案是拥有一个中心文化属性(Application.CurrentCulture是每个线程)并在工作线程的开头设置当前线程文化。 作业系统可以帮助解决这个问题,因为您可以在工作项之前和之后轻松执行通用代码,并且作业系统类可以保存其作业可访问的文化,因此您不需要全局变量。

简单的说; 不要这样做

不要在主线程( Thread.CurrentThread )之外的任何其他线程上执行任何特定于文化的格式化。 在其他线程上获得正确的文化 – 创建其他所有线程 – 只是一种痛苦,迟早你会忘记正确设置它。 最好只是避免共同的痛苦,只在你确保在正确的文化设置上的线程上进行文化特定的格式化,转换等。

您不能为每个新创建的线程执行此操作。 你应该手工完成(但我不认为为线程池线程设置文化是一个好主意!)。 也许你的应用程序应该取决于Application.CurrentCulture或其他一些全局的东西..

Windows始终将OS线程初始化为系统默认LCID,在“控制面板”的“区域和语言选项”小程序中进行配置。

不幸的是,我不得不反对这一点,并发现相反的情况。

系统安装为美国英语。 去控制面板将所有内容更改为丹麦文并复制到所有帐户。 重新启动。

运行控制台应用程序以丹麦语运行。 运行web应用程序问浏览器它说丹麦语。 从网络应用程序启动线程,它是作为美国而非丹麦推出的,我无法弄清楚原因。

我知道这个话题已经过时了,但我发现自己陷入了“操作系统文化”的问题。

我解决了这个问题:因为BackgroundWorker在UserControl中(如果它在Form中,它将是有效的……)我在构造时在UserControl(或Form)中设置了一个字段。 在DoWork事件处理程序中,我在我的操作中使用此字段。 这里的代码:

  ///  /// Culture in which the GUI creates the control. ///  private readonly CultureInfo _currentCulture; ///  /// Default constructor. ///  public MyControl() { InitializeComponent(); _currentCulture = CultureInfo.CurrentUICulture; } private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { ExampleClass.DoCultureDependentOperation(_currentCulture); }