代码之家  ›  专栏  ›  技术社区  ›  Rob Prouse

用于设置当前区域性的线程创建事件

  •  4
  • Rob Prouse  · 技术社区  · 16 年前

    我们的应用程序允许用户更改运行它所使用的区域性,并且该区域性可以不同于底层的操作系统区域性。我找到的唯一方法是为每个线程设置thread.currentThread.currentCulture和thread.currentThread.currentUICulture。

    唯一的问题是,我们必须为每个线程设置区域性,并且我们需要记住,每当我们创建一个新线程时都要这样做。如果将一个线程设置为另一个区域性,然后创建一个新的线程,它将获取操作系统的区域性,而不是创建它的线程的区域性。

    我想找个更好的方法来做这个。我只能想到两件事,但我不知道两者是否可能。

    1. 在应用程序级别设置区域性,以便所有线程都默认为该区域性。这有可能吗?
    2. 我可以在任何地方订阅线程创建事件吗?这样我就可以设置一个处理程序来设置线程创建的区域性。

    任何想法或帮助都将受到欢迎,即使我需要pinvoke到win32 API。事先谢谢。

    编辑: 我发现 this question 这是相似的,但没有找到答案。

    4 回复  |  直到 7 年前
        1
  •  1
  •   Gant    16 年前

    可能不是确切的解决方案,但是如何创建一个负责线程创建的类呢?

    class MyThreadFactory
    {
        public static Thread getThread()
        {
            Thread a = new Thread(..);
            a.CurrentCulture = xxxx;
            return a;
        }
    }
    

    用途:

    Thread newThread = MyThreadFactory.getThread();
    
        2
  •  1
  •   Jason Jackson    16 年前
    1. 您可以将所有的区域性逻辑和静态资源文件放在ui/presentation层中,并且只担心ui线程的区域性(假设此处为桌面应用程序)。这将包括资源文件中的任何翻译、任何特定于区域性的格式等。
    2. 如果第一个想法无法实现,您可以创建一个线程帮助器类,该类在创建长时间运行的线程时为您设置区域性。您还需要设置所有线程池线程的区域性。

    区域性是Windows中特定于线程的概念,而Windows中的线程实际上与进程或AppDomain无关。线程和包含区域性信息(我知道)的操作系统之间没有抽象级别,因此您必须在每个线程上设置它。

        3
  •  1
  •   Rob Prouse    11 年前

    在.NET 4.5中的CultureInfo类中添加了两个新属性,解决了这个问题。 DefaultThreadCurrentCulture DefaultThreadCurrentUICulture .

    现在可以设置这两个属性,所有新线程都将设置为默认区域性,而不是系统区域性。这些属性还将为没有显式设置其区域性的所有现有线程设置区域性。

        4
  •  0
  •   B.Spangenberg    7 年前

    只需添加到@rob prouse答案。这是一个快速演示。

    1. 设置应用程序初始化的区域性:

        if(CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol != "N$")
        {
             CultureInfo customCulture = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
             customCulture.NumberFormat.CurrencySymbol = "N$";
      
             CultureInfo.DefaultThreadCurrentCulture = customCulture;
             CultureInfo.DefaultThreadCurrentUICulture = customCulture;
         }
      
    2. 使用my.toString()上的区域性信息。

       .ToString("C", CultureInfo.DefaultThreadCurrentCulture)