保持CurrentCulture处于异步/等待状态 [英] Keep CurrentCulture in async/await

查看:83
本文介绍了保持CurrentCulture处于异步/等待状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下伪代码

string GetData()
{
  var steps = new List<Task<string>>
  {
    DoSomeStep(),
    DoSomeStep2()
  };

  await Task.WhenAll(steps);

  return SomeResourceManagerProxy.RetrieveValuesForLocalizedStrings( steps.Select(s => s.Result) );

}

此方法是从WebService调用的,我根据用户的浏览器设置在其中设置了Thread.CurrentUICulture.

This method is called from WebService, where I set Thread.CurrentUICulture according to user's browser settings.

等待后,CurrentUICulture丢失(我在不同的线程上运行).

After await, the CurrentUICulture is lost (I run on different thread).

我已通过以下方法解决了该问题:

I have solved the issue with following:

    public class MyAwaiter<T> : INotifyCompletion
    {
        private TaskAwaiter<T> waiter;
        private CultureInfo culture;

        public MyAwaiter(TaskAwaiter<T> waiter)
        {
            this.waiter = waiter;
        }

        public PreserveCultureAwaiter<T> GetAwaiter() { return this; }

        public bool IsCompleted { get { return waiter.IsCompleted; } }

        public void OnCompleted(Action continuation)
        {
            culture = Thread.CurrentThread.CurrentUICulture;
            waiter.OnCompleted(continuation);
        }

        public T GetResult()
        {
            Thread.CurrentThread.CurrentUICulture = culture;
            return waiter.GetResult();
        }
    }

    public static MyAwaiter<T> KeepCulture<T>(this Task<T> task)
    {
        return new MyAwaiter<T>(task.GetAwaiter());
    }

...

    await Task.WhenAll(steps).KeepCulture();

这有一个缺点-需要记住要在等待的每个 任务上调用KeepCulture(). (我还有一些扩展方法可以将UI文化保持在任务中.)

This has one drawback - need for remembering to call KeepCulture() on every task that is being awaited. (I have also some extension method to keep the UI culture in task).

有什么更简单的方法来保存UI文化吗?

Is there any easier way how to preserve UI culture?

推荐答案

.NET Framework中没有文化,这是一个非常臭名昭著的问题.在Windows上很难解决,文化是线程的非托管属性,因此CLR无法确保始终正确设置该属性.这使得在主线程上修改CurrentCulture是一个重大的错误.您得到的错误很难诊断.就像您在一个线程上创建的SortedList突然在另一个线程上不再排序一样. uck.

Culture does not flow in the .NET Framework, a very notorious problem. It is very hard to solve on Windows, culture is an unmanaged property of a thread so the CLR can't ensure it is always set correctly. That makes tinkering with the CurrentCulture on the main thread a big fat mistake. The bugs you get are very hard to diagnose. Like a SortedList you create on one thread that suddenly isn't sorted anymore on another. Yuck.

Microsoft在.NET 4.5中对此做了一些操作,他们添加了

Microsoft did something about it in .NET 4.5, they added the CultureInfo.DefaultThreadCurrentCulture property. Also DefaultThreadCurrentUICulture. That still does not guarantee it will be set correctly, unmanaged code you call can change it and the CLR cannot do anything about it. In other words, a bug will be much harder to diagnose. But at least you have some idea when it might change.

更新:此问题已在.NET 4.6中彻底修复,区域性现在从一个线程流向另一个线程,而CultureInfo.DefaultThreadCurrentCulture hack不再是必需的,也不再有用.在MSDN文章中针对

UPDATE: this problem was fixed thoroughly in .NET 4.6, culture now flows from one thread to another and the CultureInfo.DefaultThreadCurrentCulture hack is not longer necessary nor useful. Documented in the MSDN article for CultureInfo.CurrentCulture. Details as written right now do not appear to be entirely correct, it always flowed when I tested it and DefaultThreadCurrentCulture appear to play no role at all anymore.

这篇关于保持CurrentCulture处于异步/等待状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆