WPF - изменить культуру пользовательского интерфейса в обратном вызове асинхронной задачи - PullRequest
0 голосов
/ 19 февраля 2020

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

Теперь проверка выполняется асинхронно, и для обратного вызова в потоке пользовательского интерфейса установлено CultureInfo.CurrentUICulture. Но в конце обратного вызова CultureInfo.CurrentUICulture является откатом. Посмотрите этот пример:

MainWindow.xaml:

<StackPanel>
    <ComboBox SelectionChanged="ComboBox_Selected">
        <ComboBoxItem>en-US</ComboBoxItem>
        <ComboBoxItem>en-GB</ComboBoxItem>
        <ComboBoxItem>fr-FR</ComboBoxItem>
    </ComboBox>
    <Button Click="Button_Click">Display</Button>
</StackPanel>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void ComboBox_Selected(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine($"A - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
        var to = ((ComboBoxItem)((ComboBox)sender).SelectedItem).Content as string;
        Task.Delay(TimeSpan.FromSeconds(1)).ContinueWith(
            t => SetCurrentCulture(to),
            TaskScheduler.FromCurrentSynchronizationContext()
        );
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(CultureInfo.CurrentCulture.Name);
    }

    private static void SetCurrentCulture(string to)
    {
        Debug.WriteLine($"B - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
        var culture = new CultureInfo(to);
        CultureInfo.DefaultThreadCurrentCulture = culture;
        CultureInfo.DefaultThreadCurrentUICulture = culture;
        CultureInfo.CurrentCulture = culture;
        CultureInfo.CurrentUICulture = culture;
    }
}

Можете ли вы объяснить, почему? Как можно решить это?

1 Ответ

1 голос
/ 19 февраля 2020

Можете ли вы объяснить, почему?

Из документов :

Для приложений, предназначенных для. NET Framework 4.6 или более поздние версии, культура является частью контекста асинхронной операции. Другими словами, начиная с приложений, предназначенных для. NET Framework 4.6, асинхронные операции по умолчанию наследуют значения свойств CurrentCulture и CurrentUICulture потока, из которого они запускаются.

Как можно решить эту проблему?

Добавьте следующий переключатель в ваш файл App.config, чтобы вернуться к поведению, наблюдаемому в. NET Framework 4.5.2:

<runtime>
    <AppContextSwitchOverrides value="Switch.System.Globalization.NoAsyncCurrentCulture=true" />
</runtime>
...