c# – 这是暂时改变当前线程文化的好方法吗?

我工作在一个相当大的ASP .NET Web窗体应用程序,目前主要在美国使用.我们正在将其推广到世界其他地区,这当然意味着我们正在努力将应用的所有领域进行本地化.一般来说,我们的方法是在每个请求开始时设置当前线程的CurrentCulture和CurrentUICulture属性,以支持基于当前用户的区域设置的正确格式化和资源提取.

然而,在某些情况下,我们需要使用不同于当前用户的文化的文化来运行某些代码.例如,“用户A”居住在德国,但适用于与法国其他公司开展业务的公司.当“用户A”想要为这些法国公司之一创建发票(PDF)时,我们希望发票生成代码以“fr-FR”文化而不是“de-DE”文化运行.

我已经考虑过几种方法,很容易就这样做,想知道我是否正确地进行这项工作.我的主要关注点在于性能和线程安全.

一种方法涉及一种静态方法,旨在使用提供的文化来运行给定的任务.这样的事情

 public static void RunWithCulture(CultureInfo culture, Action task)
    {
        if (culture == null)
            throw new ArgumentNullException("culture");

        var originalCulture = new
                                  {
                                      Culture = Thread.CurrentThread.CurrentCulture,
                                      UICulture = Thread.CurrentThread.CurrentUICulture
                                  };

        try
        {
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
            task();
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = originalCulture.Culture;
            Thread.CurrentThread.CurrentUICulture = originalCulture.UICulture;
        }
    }

然后可以像这样调用此方法:

var customerCulture = new CultureInfo(currentCustomer.Locale);
CultureRunner.RunWithCulture(customerCulture, () => invoiceService.CreateInvoice(currentCustomer.CustomerId));

我还考虑创建一个实现IDisposable的类,该类将负责在其ctor中设置线程文化,然后使用Dispose方法返回原始文化,因此可以像下面这样调用:

var customerCulture = new CultureInfo(currentCustomer.Locale);
using(new CultureRunner(currentCustomer.Locale))
{
  invoiceService.CreateInvoice(currentCustomer.CustomerId);
}

我这样做都错了吗?哪些,哪些方法更可取?

我喜欢使用方法.我还创建一个扩展方法来使事情更好地阅读:

var customerCulture = new CultureInfo(currentCustomer.Locale);  
using (customerCulture.AsCurrent()) {
  invoiceService.CreateInvoice(currentCustomer.CustomerId);
}

这样的事情

public static class CultureInfoExtensions {
  public static IDisposable AsCurrent(this CultureInfo culture) {
    return new CultureRunner(culture);
  }
}

或者,如果始终是您的客户对象设定文化,另一种扩展方法将进一步提高抽象性:

using (currentCustomer.CultureContext()) {
  invoiceService.CreateInvoice(currentCustomer.CustomerId);
}
http://stackoverflow.com/questions/5793000/is-this-a-good-approach-for-temporarily-changing-the-current-threads-culture

转载注明原文:c# – 这是暂时改变当前线程文化的好方法吗?