简体   繁体   English

是否可以为.NET应用程序或仅为线程设置CultureInfo?

[英]Is it possible to set the CultureInfo for an .NET application or just a thread?

I've an application written in C# which has no GUI or UI, but instead writes files that are parsed by another application (in XML and others). 我有一个用C#编写的应用程序,它没有GUI或UI,但是写的是由另一个应用程序(以XML和其他形式)解析的文件。

I have a customer whose CultureInfo has the NumberDecimalSeparator set to a comma, which causes parsing errors with floating point numbers (PI would end up as 3,1415 ). 我有一个客户,其CultureInfo将NumberDecimalSeparator设置为逗号,这会导致解析带有浮点数的错误(PI最终为3,1415 )。

I'd like a way to set the CultureInfo globally within the application, for all threads. 我想为所有线程在应用程序中全局设置CultureInfo的方法。 I've tried: 我试过了:

  1. The (apparently) customary approach of setting CurrentThread.CurrentCulture as the first line in Main() but it appears to get reset. (显然)将CurrentThread.CurrentCulture设置为Main()的第一行的惯用方法,但似乎被重置了。
  2. A variation/expansion on http://www.codeproject.com/KB/cs/Change_App_Culture.aspx http://www.codeproject.com/KB/cs/Change_App_Culture.aspx的变体/扩展
  3. Do the same (#1) on the explicitly created threads in the application. 对应用程序中显式创建的线程执行相同的操作(#1)。

And changing to use explicit formatting is not an option (150K+ lines, most written by former employees). 更改为使用显式格式不是一个选择(超过15万行,大多数由前员工编写)。

[Edit] The application binds to a socket and handles requests from dedicated clients. [编辑]该应用程序绑定到套接字并处理来自专用客户端的请求。 Depending on the request type it spawns different handler classes. 根据请求类型,它产生不同的处理程序类。

Sorry, when I first posted I should have clarified in #1 that ( I though ) I had done this in all of the handlers that were explicitly spawned, too. 抱歉,当我第一次发布时,我应该在#1中阐明( 我虽然 ), 我也已经在所有显式产生的处理程序中做到了这一点。

It turns out that I missed the thread/handler that was causing the problem. 原来,我错过了导致问题的线程/处理程序。 So the application is working properly now, but the question remains about if the culture can be set on all threads. 因此,应用程序现在可以正常工作,但是问题仍然在于是否可以在所有线程上设置区域性。

If it could iterate over all threads, it would solve the issue, too. 如果它可以遍历所有线程,那么它也将解决该问题。 So: 所以:

How can I get all Thread objects (not ProcessThread ) in the current process? 如何获取当前进程中的所有Thread对象(不是ProcessThread )?

在.NET 4.5中,您可以使用CultureInfo.DefaultThreadCurrentCulture

Unfortunately, every new thread starts with system locale information, even if it's started from a thread that's had its locale changed to something else. 不幸的是,每个新线程都以系统语言环境信息开头,即使它是从已将其语言环境更改为其他内容的线程开始的。

This was a huge gotcha I ran into in one of our apps when using a BackgroundWorker to load a file. 使用BackgroundWorker加载文件时,这是我遇到的一个巨大难题。

The approach I've used successfully is to set the locale on the startup thread, and then use a thread factory to create threads with the "application locale." 我成功使用的方法是在启动线程上设置语言环境,然后使用线程工厂通过“应用程序语言环境”创建线程。 For BackgroundWorkers you can use either a factory or a derived class, as Thread is sealed while BackgroundWorker is not. 对于BackgroundWorkers,您可以使用工厂或派生类,因为Thread是密封的,而BackgroundWorker不是。

I don't think you can set the culture for the whole application, but you can set the culture explicilty whenever you create a thread: 我认为您不能为整个应用程序设置区域性,但是只要创建线程,就可以设置区域性公开性:

using System;
using System.Globalization;
using System.Threading;

class Program {

    static void thread_test() {
        Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName);
    }

    public static void Main(params string[] args) {
        Thread t = new Thread(thread_test);
        t.CurrentCulture = new CultureInfo("it-it");
        t.Start();
        t.Join();
    }
}

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM