用于设置 CurrentCulture 的线程创建事件

发布于 2024-07-10 23:37:04 字数 661 浏览 8 评论 0原文

我们的应用程序允许用户更改其运行所在的文化,并且该文化可以与底层操作系统文化不同。 我发现执行此操作的唯一方法是为每个线程设置 Thread.CurrentThread.CurrentCulture 和 Thread.CurrentThread.CurrentUICulture。

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

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

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

即使我需要 PInvoke 到 Win32 API,任何想法或帮助都会受到欢迎。 提前致谢。

编辑:我发现这个问题< /a> 类似,但没有找到答案。

Our application allows the user to change the Culture that they run it under and that culture can be different than the underlying OS Culture. The only way that I have found of doing this is by setting Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture for every thread.

The only problem with this is that we must set the culture for every thread and we need to remember to do this whenever we create a new thread. If you set a thread to another culture, then create a new thread, it gets the culture of the OS, not of the thread that created it.

I would like to find a better way of doing this. I can only think of two things, but I don't know if either are possible.

  1. Set the culture at the application level so that all threads default to that culture. Is this possible?
  2. Is there a thread creation event anywhere that I can subscribe to? This way I can set up one handler to set the culture on thread creation.

Any ideas or help would be welcome, even if I need to PInvoke down to the Win32 API. Thanks in advance.

EDIT: I found this question which is similar, but no answer was found.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜清冷一曲。 2024-07-17 23:37:04

可能不是确切的解决方案,但是创建一个负责线程创建的类怎么样?

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

用法:

Thread newThread = MyThreadFactory.getThread();

May not be the exact solution, but how about creating a class that responsible for your thread creation ?

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

Usage:

Thread newThread = MyThreadFactory.getThread();
懵少女 2024-07-17 23:37:04
  1. 您可以将所有区域性逻辑和静态资源文件放置在 UI/表示层中,并且只关心 UI 线程的区域性(假设此处为桌面应用程序)。 这将包括资源文件中的任何翻译、任何区域性特定格式等。
  2. 如果第一个想法无法实现,您可以创建一个线程帮助器类,在创建长时间运行的线程时为您设置区域性。 您还需要设置所有线程池线程的区域性。

文化是 Windows 中特定于线程的概念,Windows 中的线程实际上与进程或应用程序域无关。 线程和保存文化信息(据我所知)的操作系统之间没有抽象级别,因此您必须在每个线程上设置它。

  1. You could place all of your culture logic and static resource files in the UI/Presentation layer and only worry about the UI thread's culture (assuming Desktop app here). This would include any translations that are in resource files, any culture-specific formatting, etc.
  2. If the first idea cannot be implemented, you might create a thread helper class that sets the culture for you when long-running threads are created. You will also need to set the culture of all the thread-pool threads.

Culture is a thread-specific concept in Windows, and threads in Windows are actually agnostic of a process or appdomain. There is no level of abstraction between a thread and the OS that holds culture info (that I know of), so you have to set it on each thread.

奢华的一滴泪 2024-07-17 23:37:04

.NET 4.5 中的 CultureInfo 类添加了两个新属性来解决此问题,DefaultThreadCurrentCultureDefaultThreadCurrentUICulture< /a>.

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

Two new properties were added to the CultureInfo class in .NET 4.5 which solve this problem, DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture.

Now you can set these two properties and all new threads will be set to the default culture instead of the system culture. These properties will also set the culture for all existing threads that do no explicitly have their culture set.

意中人 2024-07-17 23:37:04

只是为了添加@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. 在我的 .ToString() 上使用区域性信息。

     .ToString("C", CultureInfo.DefaultThreadCurrentCulture) 
      

Just to add to @Rob Prouse answer. Here is a quick demonstration.

  1. Setting the culture on App intialization :

      if(CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol != "N$")
      {
           CultureInfo customCulture = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
           customCulture.NumberFormat.CurrencySymbol = "N$";
    
           CultureInfo.DefaultThreadCurrentCulture = customCulture;
           CultureInfo.DefaultThreadCurrentUICulture = customCulture;
       }
    
  2. Using the culture info on my .ToString().

     .ToString("C", CultureInfo.DefaultThreadCurrentCulture)
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文