Итак, я проводил несколько тестов, в которых мне нужно запустить несколько потоков и выполнить некоторые синтаксические анализы даты и времени, изменяющие CurrentCulture, и задался вопросом, есть ли вообще какая-либо разница между CultureInfo.CurrentCulture
и Thread.CurrentThread.CurrentCulture
Для обоих intellisense говорит мне:
Gets or sets the culture for the current thread.
Returns:
An object that represents the culture for the current thread.
Мой код:
using System.Globalization;
Console.WriteLine("Hello, World!");
string dateValueString = "05/07/2022";
CultureInfo enGB = new CultureInfo("en-GB");
CultureInfo enUS = new CultureInfo("en-US");
DateTime result = DateTime.Now;
DateTime result2 = DateTime.Now;
Console.WriteLine($"CurrentCulture: {CultureInfo.CurrentCulture.Name} - ThreadCulture: {Thread.CurrentThread.CurrentCulture.Name}");
if (DateTime.TryParse(dateValueString, enGB, DateTimeStyles.None, out result))
{
Console.WriteLine($"Original: {dateValueString} Parsed: {result}. Day: {result.Day}. Month: {result.Month}. Year: {result.Year}");
result2 = DateTime.Parse(dateValueString);
Console.WriteLine($"[Parse]Original: {dateValueString} Parsed: {result2}. Day: {result2.Day}. Month: {result2.Month}. Year: {result2.Year}");
}
Console.WriteLine(System.Environment.NewLine);
Thread.CurrentThread.CurrentCulture = enGB;
Console.WriteLine($"CurrentCulture: {CultureInfo.CurrentCulture.Name} - ThreadCulture: {Thread.CurrentThread.CurrentCulture.Name}");
if (DateTime.TryParse(dateValueString, enGB, DateTimeStyles.None, out result))
{
Console.WriteLine($"Original: {dateValueString} Parsed: {result}. Day: {result.Day}. Month: {result.Month}. Year: {result.Year}");
result2 = DateTime.Parse(dateValueString);
Console.WriteLine($"[Parse]Original: {dateValueString} Parsed: {result2}. Day: {result2.Day}. Month: {result2.Month}. Year: {result2.Year}");
}
Console.WriteLine(System.Environment.NewLine);
Thread.CurrentThread.CurrentCulture = enUS;
Console.WriteLine($"CurrentCulture: {CultureInfo.CurrentCulture.Name} - ThreadCulture: {Thread.CurrentThread.CurrentCulture.Name}");
if (DateTime.TryParse(dateValueString, enGB, DateTimeStyles.None, out result))
{
Console.WriteLine($"Original: {dateValueString} Parsed: {result}. Day: {result.Day}. Month: {result.Month}. Year: {result.Year}");
result2 = DateTime.Parse(dateValueString);
Console.WriteLine($"[Parse]Original: {dateValueString} Parsed: {result2}. Day: {result2.Day}. Month: {result2.Month}. Year: {result2.Year}");
}
Console.WriteLine(System.Environment.NewLine);
new Thread(() =>
{
Thread.CurrentThread.CurrentCulture = enGB;
Console.WriteLine($"CurrentCulture: {CultureInfo.CurrentCulture.Name} - ThreadCulture: {Thread.CurrentThread.CurrentCulture.Name}");
if (DateTime.TryParse(dateValueString, enGB, DateTimeStyles.None, out result))
{
Console.WriteLine($"[Thread] Original: {dateValueString} Parsed: {result}. Day: {result.Day}. Month: {result.Month}. Year: {result.Year}");
result2 = DateTime.Parse(dateValueString);
Console.WriteLine($"[Thread][Parse]Original: {dateValueString} Parsed: {result2}. Day: {result2.Day}. Month: {result2.Month}. Year: {result2.Year}");
}
}).Start();
Console.WriteLine(System.Environment.NewLine);
Вывод:
CurrentCulture: es-ES - ThreadCulture: es-ES
Original: 05/07/2022 Parsed: 05/07/2022 0:00:00. Day: 5. Month: 7. Year: 2022
[Parse]Original: 05/07/2022 Parsed: 05/07/2022 0:00:00. Day: 5. Month: 7. Year: 2022
CurrentCulture: en-GB - ThreadCulture: en-GB
Original: 05/07/2022 Parsed: 05/07/2022 00:00:00. Day: 5. Month: 7. Year: 2022
[Parse]Original: 05/07/2022 Parsed: 05/07/2022 00:00:00. Day: 5. Month: 7. Year: 2022
CurrentCulture: en-US - ThreadCulture: en-US
Original: 05/07/2022 Parsed: 7/5/2022 12:00:00 AM. Day: 5. Month: 7. Year: 2022
[Parse]Original: 05/07/2022 Parsed: 5/7/2022 12:00:00 AM. Day: 7. Month: 5. Year: 2022
CurrentCulture: en-GB - ThreadCulture: en-GB
[Thread] Original: 05/07/2022 Parsed: 05/07/2022 00:00:00. Day: 5. Month: 7. Year: 2022
[Thread][Parse]Original: 05/07/2022 Parsed: 05/07/2022 00:00:00. Day: 5. Month: 7. Year: 2022
@Enigmativity, если между этими двумя статическими свойствами есть какие-либо различия, о которых мне следует беспокоиться при работе с потоками.
Разница между
CultureInfo.CurrentCulture
иThread.CurrentThread.CurrentCulture
Удивительно, но никто раньше не задавал этот конкретный вопрос, хотя вместо этого люди спрашивали о Application.CurrentCulture
.
В любом случае: Thread.CurrentThread.CurrentCulture
(или Thread.CurrentCulture
, если быть точным) геттер свойств просто возвращает CultureInfo.CurrentCulture
, , как видно из исходного кода :
class Thread
{
// ...
public CultureInfo CurrentCulture
{
get
{
RequireCurrentThread();
return CultureInfo.CurrentCulture;
}
set
{
if (this != CurrentThread)
{
SetCultureOnUnstartedThread(value, uiCulture: false);
return;
}
CultureInfo.CurrentCulture = value;
}
}
// ...
}
Итак, что касается вас: нет никакой разницы, и ваши тесты избыточны.
И если вам интересно, CultureInfo.CurrentCulture
— это простое свойство, которое считывает/записывает в поле \[ThreadStatic\] (так что реальная логика, я полагаю, находится в CLR):
public partial class CultureInfo : IFormatProvider, ICloneable
{
// ...
[ThreadStatic]
private static CultureInfo? s_currentThreadCulture;
[ThreadStatic]
private static CultureInfo? s_currentThreadUICulture;
// ...
public static CultureInfo CurrentCulture
{
get
{
return s_currentThreadCulture ??
s_DefaultThreadCurrentCulture ??
s_userDefaultCulture ??
InitializeUserDefaultCulture();
}
set
{
ArgumentNullException.ThrowIfNull(value);
if (s_asyncLocalCurrentCulture == null)
{
Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
}
s_asyncLocalCurrentCulture!.Value = value;
}
}
// ...
}
Что вы у нас спрашиваете?