为整个appdomain定义文化

时间:2010-09-13 07:45:42

标签: .net multithreading appdomain

我正在创建一个运行多个线程的Windows服务。 我可以设置整个appDomain的文化,而不是分别将它设置到每个线程吗?

3 个答案:

答案 0 :(得分:16)

对于4.5默认应用程序域文化,可以通过CultureInfo类设置:

答案 1 :(得分:8)

这是不可能的。当Windows创建线程时,线程会获得其默认文化,该线程是从控制面板+区域和语言中配置的系统默认语言环境初始化的。相关的Win32 API函数是Get / SetThreadLocale()。

CLR中没有任何机制可以为一个线程添加另一个默认值。线程的一个常见场景是启动由非托管代码创建的生命并运行大量非托管代码,偶尔会回调托管代码。该托管代码将在Thread.CurrentCulture设置为非托管代码选择的区域性的情况下运行。如果非托管代码未调用SetThreadLocale(),则为Windows默认值。对CLR进行更改会导致非托管代码出现无法诊断的错误。

当然你可以明确地覆盖它,但这很难做到。细微的格式错误很容易看到,当你使用隐含依赖于字符串整理顺序的数据结构时,它会变得很难。 SortedList突然无法在列表中找到实际存在的元素。控制它也很困难,整个.NET框架中有很多小的线程池线程回调。

不要乱用它来避免陷入这样的陷阱,要么依赖系统默认值,要么明确应用CultureInfo。


更新:如Thomas所述,解决方案将在.NET 4.5中提供,它为CultureInfo类提供了一个新属性来设置appdomain的默认文化。 MSDN文档are here。与文档中输入托管代码的非托管线程的确切交互不是很清楚,如果您允许本机代码进行回调,请务必检查这一点,例如通过pinvoke,Marshal.GetFunctionPointerForDelegate()或COM对象的事件。


UPDATE2:在.NET 4.6中再次更改,文化现在从一个线程流向另一个线程,因此最糟糕的故障模式得到了解决。在CultureInfo.CurrentCulture的MSDN文章中阅读有关它的详细信息。你必须明确地以4.6为目标才能获得好处。

答案 2 :(得分:3)

您可以使用自定义方法来自动触发线程并设置文化:

static bool StartThread(WaitCallback callback, object state)
{
    return ThreadPool.QueueUserWorkItem(s =>
    {
        // Set the culture
        Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");
        // invoke the callback
        callback(s);
    }, state);
}

当你需要开始一个新线程时,只需使用这个方法:

StartThread(state => { /** Do some processing on a new thread **/ }, null);