如何确保对特定库的调用具有不同的 CultureInfo.CurrentCulture

How to ensure different CultureInfo.CurrentCulture for calls to specific library

提问人:Liero 提问时间:11/7/2023 最后编辑:Liero 更新时间:11/23/2023 访问量:73

问:

我有一个使用但必须设置为正常运行的第三方库。CultureInfo.CurrentCultureInvariantCulture

我的多线程应用程序使用本地化的 .CultureInfo.CurrentCulture

public string WrappedCallTo3rdPartyLibrary(string input)
{
    //use new thread to isolate CurrentCulture side effects.
    return Task.Factory.StartNew(() =>
    {
        CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
        string result = _3rdPartyLibrary.SynchronousCall(input);
        return result;
    }).GetAwaiter().GetResult();
}
  1. 这是为_3rdPartyLibrary设置区域性信息的正确方法吗?
  2. 我是否可以保证上述方法不会影响父线程?

编辑:

我最初尝试了同步调用,但我怀疑它有副作用(父线程或以前启动的子线程受到影响?

public string WrappedCallTo3rdPartyLibrary(string input)
{
    var ciBackup = CultureInfo.CurrentCulture;
    try
    {
       CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
       return _3rdPartyLibrary.SynchronousCall(input);
    }
    finally
    { 
        CultureInfo.CurrentCulture = ciBackup ;
    }
}
C# 多线程处理 .net-core 任务并行库 cultureinfo

评论

1赞 Panagiotis Kanavos 11/7/2023
正确的解决方案(在所有 .NET 类中使用的解决方案)是将 CultureInfo 作为参数传递。所有 、 、 方法都采用 CultureInfo 或 IFormatProvider 参数ParseTryParseToStringFormat
0赞 Panagiotis Kanavos 11/7/2023
真正的代码是做什么的?为什么?设置任务线程的 CI 早在 2010-12 年就已使用,然后才开始保留 CultureInfo。您可以使用,但必须确保它返回到其原始值,否则在此线程上运行的下一个任务将运行意外的 CI。Task.Factory.StartNewasync/awaitThread.CurrentCulture = = CultureInfo.InvariantCulture;
0赞 Panagiotis Kanavos 11/7/2023
线程或应用程序使用什么区域性?如果你根本不设置文化会怎样?在 .NET Core 中,默认情况下仅包含固定区域性,以减小部署大小。除非在 csproj 或生成环境中进行设置,否则一切都将使用固定区域性运行<InvariantGlobalization>false</InvariantGlobalization>DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
0赞 Liero 11/7/2023
@PanagiotisKanavos:两年前,我提出了作为参数的功能请求;)我的应用程序区域性用作小数点分隔符,它在生产中工作正常。查看我的编辑,了解我开始新的原因CultureInfo,Task
0赞 Theodor Zoulias 11/7/2023
@Magnus出于好奇,你为什么要删除你的答案?如果可以的话,我会投赞成票!

答:

-1赞 Nick 11/23/2023 #1

您建议的同步调用应该不会产生副作用,即使它是在线程池上执行的,即在任务中执行。

顺便说一句,您应该避免 .更好地使用和.Task.GetAwaiter().GetResult();Task.Wait()Task.Result

更新

让我引用文档

此方法旨在供编译器使用,而不是直接在代码中使用。

评论

1赞 Liero 11/23/2023
为什么 Wait() 比 GetAwaiter() 更好?GetResult()?
0赞 Nick 11/23/2023
@Liero,请参阅上面更新的答案。
0赞 Theodor Zoulias 11/23/2023
越好.GetAwaiter().GetResult()
0赞 Nick 11/23/2023
尽管如此,文档并不建议这样做。除非有充分的理由,否则我会避免.在这种特殊情况下,我没有看到这样的。.GetAwaiter().GetResult()