更改线程区域性 .NET Framework 4.6 及更高版本
Change thread culture .NET Framework 4.6 and later versions
我正在尝试更改一个新线程 CultureInfo
,如下例所示,但是:
- 尝试 1:
SetCulture1()
没有改变我的话题
尝试 2:SetCulture2()
我遇到异常 "System.InvalidOperationException: instance is read-only"(当设置 CurrencyDecimalSeparator 时)
static void Main(string[] args)
{
Thread th = new Thread(thread_test);
// nothing happens
SetCulture1(th);
// exception System.InvalidOperationException: instance is read-only
SetCulture2(th);
th.Start();
}
public static void SetCulture1(System.Threading.Thread thread)
{
var ci = new System.Globalization.CultureInfo("pt-BR");
ci.NumberFormat.CurrencyDecimalSeparator = ".";
thread.CurrentCulture = ci; // <-- after this culture info not change
if (thread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator != ".")
{
Console.WriteLine("Nothing happened");
Console.ReadKey();
}
}
public static void SetCulture2(System.Threading.Thread thread)
{
thread.CurrentCulture = new System.Globalization.CultureInfo("pt-BR");
thread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator = "."; // <-- exception throws here
}
static void thread_test()
{
Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName);
}
我注意到在 .net 4.6 之前此示例有效。
4.6 有什么变化吗?
谢谢!
虽然这种奇怪的情况没有答案 (Microsoft bug report),但我找到了在代码开头设置 DefaultThreadCurrentCulture 的解决方法(主要方法):
var ci = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.LCID);
ci.NumberFormat.CurrencyDecimalSeparator = ".";
ci.NumberFormat.CurrencyGroupSeparator = ",";
ci.NumberFormat.NumberDecimalSeparator = ".";
ci.NumberFormat.NumberGroupSeparator = ",";
ci.NumberFormat.PercentDecimalSeparator = ".";
ci.NumberFormat.PercentGroupSeparator = ",";
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = ci;
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = ci;
我正在尝试更改一个新线程 CultureInfo
,如下例所示,但是:
- 尝试 1:
SetCulture1()
没有改变我的话题 尝试 2:
SetCulture2()
我遇到异常 "System.InvalidOperationException: instance is read-only"(当设置 CurrencyDecimalSeparator 时)static void Main(string[] args) { Thread th = new Thread(thread_test); // nothing happens SetCulture1(th); // exception System.InvalidOperationException: instance is read-only SetCulture2(th); th.Start(); } public static void SetCulture1(System.Threading.Thread thread) { var ci = new System.Globalization.CultureInfo("pt-BR"); ci.NumberFormat.CurrencyDecimalSeparator = "."; thread.CurrentCulture = ci; // <-- after this culture info not change if (thread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator != ".") { Console.WriteLine("Nothing happened"); Console.ReadKey(); } } public static void SetCulture2(System.Threading.Thread thread) { thread.CurrentCulture = new System.Globalization.CultureInfo("pt-BR"); thread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator = "."; // <-- exception throws here } static void thread_test() { Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName); }
我注意到在 .net 4.6 之前此示例有效。 4.6 有什么变化吗?
谢谢!
虽然这种奇怪的情况没有答案 (Microsoft bug report),但我找到了在代码开头设置 DefaultThreadCurrentCulture 的解决方法(主要方法):
var ci = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.LCID);
ci.NumberFormat.CurrencyDecimalSeparator = ".";
ci.NumberFormat.CurrencyGroupSeparator = ",";
ci.NumberFormat.NumberDecimalSeparator = ".";
ci.NumberFormat.NumberGroupSeparator = ",";
ci.NumberFormat.PercentDecimalSeparator = ".";
ci.NumberFormat.PercentGroupSeparator = ",";
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = ci;
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = ci;