【问题标题】:WPF - Change UI culture in callback of asynchrone taskWPF - 在异步任务的回调中更改 UI 文化
【发布时间】:2020-02-19 08:51:33
【问题描述】:

在我的应用程序中,用户可以切换语言。在应用更改之前,会进行检查。 在完全同步的情况下,这项工作正常。

现在,检查是异步的,并且 UI 线程集上的回调 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;
    }
}

你能解释一下为什么吗? 如何解决这个问题?

【问题讨论】:

  • 你为什么使用ContinueWith?而不仅仅是await Task.Delay(1000); SetCurrentCulture(to);
  • 因为真实的代码比较复杂。我尝试使用 await/async 并获得相同的行为。
  • 您是否尝试过通过调度程序进行设置? Dispatcher?.Invoke(() =&gt; { //culture stuff here });
  • 我试一试,同样的结果。

标签: c# .net wpf task cultureinfo


【解决方案1】:

你能解释一下原因吗?

来自docs

对于面向 .NET Framework 4.6 或更高版本的应用,区域性是异步操作上下文的一部分。换句话说,从面向 .NET Framework 4.6 的应用开始,异步操作默认继承启动它们的线程的 CurrentCultureCurrentUICulture 属性的值。

如何解决这个问题?

将以下开关添加到您的 App.config 文件以切换回 .NET Framework 4.5.2 中的行为:

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

【讨论】:

  • 这项工作,谢谢。文档说子任务继承了文化,但没有解释为什么它会回滚。
  • 4.6 或更高版本,文化与任务挂钩?
  • @Orwel:是的,它是异步方法上下文的一部分。
猜你喜欢
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
相关资源
最近更新 更多