在.Net中:将CurrentCulture保留在新线程上的最佳方法?
在 .Net 4.0 WPF 项目中,我们需要在每个线程上保留与主线程相同的 CurrentCulture。
鉴于此,我们可以使用如下代码初始化新线程的区域性:
将信息保留在变量(上下文)中
context.CurrentCulture = Thread.CurrentThread.CurrentCulture; context.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
在新线程上,从保存的上下文进行初始化
Thread.CurrentThread.CurrentCulture = context.CurrentCulture; Thread.CurrentThread.CurrentUICulture = context.CurrentUICulture;
但在这个 TPL、异步编程和 lambda 委托的时代,感觉不太对劲。
是的,我们实际上可以在应用程序运行时改变文化,但那是另一回事了。
您知道我们应该初始化以跟踪的任何设置、属性或配置吗?
In a .Net 4.0 WPF project, we need to keep the same CurrentCulture on each thread then we have on the main thread.
Given, we can initialize a new thread's culture with code like the following:
Keep the information in a variable (context)
context.CurrentCulture = Thread.CurrentThread.CurrentCulture; context.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
On the new thread, initialize from the saved context
Thread.CurrentThread.CurrentCulture = context.CurrentCulture; Thread.CurrentThread.CurrentUICulture = context.CurrentUICulture;
But in this age of TPL, async programming and lambda delegates, it does not feel right.
And yes, we actually can change the culture while the application is running, but that is another story.
Do you know of any setting, property or config we should initialize to keep track?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
没有什么好办法,不惜一切代价避免这种情况。根本问题是文化不是 Thread.ExecutionContext 的一部分,它不会从一个线程流到另一个线程。这是一个无法解决的问题,文化是本机 Windows 线程的属性。它将始终初始化为在控制面板的区域和语言小程序中选择的系统区域性。
对文化进行临时的线程本地更改很好,尝试将“进程”切换到另一种文化会导致您花费数月时间寻找错误。字符串排序顺序是最严重的问题根源。
编辑:此问题已在 .NET 4.5 中通过 CultureInfo.DefaultThreadCurrentCulture 和 DefaultThreadCurrentUICulture 属性修复。
编辑:并在 .NET 4.6 中得到了真正的解决方案,文化现在从一个线程流向另一个线程。有关详细信息,请查看 MSDN 文章 CultureInfo.CurrentCulture。请注意,描述与行为不太相符,需要进行测试。
There is no good way, avoid this at all cost. The fundamental problem is that culture is not part of the Thread.ExecutionContext, it doesn't flow from one thread to another. This is a unsolvable problem, culture is a property of a native Windows thread. It will always be initialized to the system culture as selected in Control Panel's Region and Language applet.
Making temporary thread-local changes to the culture is fine, trying to switch 'the process' to another culture is a source of bugs you'll be hunting for months. The string collation order is the nastiest source of problems.
EDIT: this problem was fixed in .NET 4.5 with the CultureInfo.DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture properties.
EDIT: and got the real solution in .NET 4.6, culture now flows from one thread to another. Check the MSDN article for CultureInfo.CurrentCulture for details. Beware that the description does not quite match behavior, testing required.
我不明白为什么帕桑特先生对此发出警告,同时又说对文化进行“临时”“线程本地”更改很好。没有一种线程文化是真正的线程本地的——正如我们所见,任何可以通过公共属性引用线程的东西都可以使用它。如果短时间改变可以,那为什么不能改变更长的时间呢?你在哪里越界了,为什么?
我也不太理解OP的感觉,即“不应该”编写代码来复制他想要复制的内容。您可能想将此代码放在可以重用它的地方,但除此之外,我真的没有看到代码的问题。在我的书中,它比我见过的任何 lambda 表达式都更加简单和精彩,而且它可以很好地完成这项工作。至少,为了漂亮而编写漂亮的代码不是我的风格。
你可以这样做:
I don't understand why Mr. Passant warns about this and simultaneously says it's fine making "temporary" "thread-local" changes to the culture. No thread culture is truly thread-local - it's available to anything that can reference the thread via public properties, as we've seen. And if it's OK to change it for a short time, then why isn't it ok to change it for a longer time? Where do you cross the line, and why?
Nor do I really understand the OP's feeling that it "shouldn't be necessary" to write code to copy the stuff he wants to copy. You may want to put this code somewhere where you can reuse it, but apart from that I really don't see the problem with the code. In my book, it's rather more straightforward and wonderful than any lambda expression I've ever seen, and it would do the job quite nicely. Writing fancy code for the sake of it being fancy is not my style, at least.
You could do something like this:
顺便说一句,我突然意识到,虽然默认区域性来自 Windows 的“区域设置”,但它可能在 .NET 配置中被覆盖。
如果这是一个 ASP.NET 应用程序,您将使用
web.config
中的globalization
元素。我可能会从这里开始了解 WPF 中的本地化:http ://msdn.microsoft.com/en-us/library/ms788718.aspx#workflow_to_localize
(是我,还是微软使用全球化和本地化这两个词,相当令人困惑,可以互换?)
By the way, it just dawns upon me that although the default culture comes from Windows' "Regional Settings", it can probably be overridden in the .NET configuration.
If this was an ASP.NET app you'd use the
globalization
element inweb.config
. I'd probably start out somewhere like here to learn about localization in WPF:http://msdn.microsoft.com/en-us/library/ms788718.aspx#workflow_to_localize
(Is it me, or does Microsoft use the words globalization and localization, rather confusingly, interchangeably?)
当我使用 TPL 创建任务时,我总是通过当前 UI 线程的文化。请参阅下面的示例代码。
我需要通过 uiculture 来解析正确的translation.resx 进行翻译
When i Create Tasks with the TPL i always Pass the Culture fomr the Current UI-Thread. See sample Code below.
I needed to pass the uiculture to resolve the correct translation.resx for translation