Разница между CultureInfo.CurrentCulture и Thread.CurrentThread.CurrentCulture

Итак, я проводил несколько тестов, в которых мне нужно запустить несколько потоков и выполнить некоторые синтаксические анализы даты и времени, изменяющие 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 19.11.2022 22:21

@Enigmativity, если между этими двумя статическими свойствами есть какие-либо различия, о которых мне следует беспокоиться при работе с потоками.

blfuentes 20.11.2022 08:09
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Разница между 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;
        }
    }

    // ...
}

Другие вопросы по теме