执行任务时,CurrentCulture设置为任务创建器CurrentCulture

本文关键字:CurrentCulture 任务 创建 设置 执行任务 | 更新日期: 2023-09-27 18:15:27

我有一个使用任务的应用程序。我们还修改了cultureInfo(我们使用EN-US语言,但保留日期/数字格式),并且我们使用。net 4.0。

应用程序有很多线程和任务,并且我们有一个用于创建任务/线程的工厂。

对于线程,我们有以下代码,以确保每个线程都以正确的CurrentCulture启动:
//This is basically only the constructor, but it describe well how we create the Thread:
public MonitoredThread(ThreadStart threadStart, string name, bool isBackground = false)
{
    m_threadStart = threadStart;
    m_name = name;
    m_isBackground = isBackground;
    Thread = new Thread(ThreadWorker)
    {
        Name = name,
        IsBackground = isBackground,
        CurrentCulture = CustomCultureInfo.CurrentCulture,
        CurrentUICulture = CustomCultureInfo.CurrentCulture
    };
}

但是对于Tasks,我不知道如何实现这种机制:

public static Task ExecuteTask(Action action, string name)
{
    MonitoredTask task = new MonitoredTask(action, name);
    return Task.Factory.StartNew(task.TaskWorker);
}

任何想法?

执行任务时,CurrentCulture设置为任务创建器CurrentCulture

我不确定您是否真的需要MonitoredTask。您可以使用闭包捕获自定义区域性:

public static Task ExecuteTask(Action action, string name)
{
   var customCulture = CustomCultureInfo.CurrentCulture;
   return Task.Factory.StartNew(() => 
   {
       // use customCulture variable as needed
      // inside the generated task.
   });
}

另一种方法是使用适当的过载(Action<object>Func<object, TResult>)将当前培养物作为object state传递:

public static Task ExecuteTask(Action action, string name)
{
   var customCulture = CustomCultureInfo.CurrentCulture;
   return Task.Factory.StartNew((obj) => 
   {
       var culture = (CultureInfo) obj;
       // use customCulture variable as needed
      // inside the generated task.
   }, customCulture);
}

我肯定选前者。

有关闭包的更多信息,请参见什么是'closures'在。net ?

在。net 4.5中,您可以为当前应用程序域(MSDN)中的所有线程设置默认区域性:

CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

这样你就有了应用程序中所有任务和线程的统一文化。

为了给@Yuval Itzchakov的回答添加更多细节,我通常为TaskFactory类创建一些保留文化的扩展方法(我通常还添加一个接收将任何给定属性设置为执行线程的操作的方法:

#region StartNewWithPersistedCulture methods
public static Task<TResult> StartNewWithPersistedCulture<TResult>(
    this TaskFactory taskFactory, Func<TResult> function, CancellationToken cancellationToken = default (CancellationToken), TaskCreationOptions creationOptions = default (TaskCreationOptions))
{
    if (taskFactory == null) throw new ArgumentNullException("taskFactory");
    if (function == null) throw new ArgumentNullException("function");
    var currentCulture = Thread.CurrentThread.CurrentCulture;
    var currentUICulture = Thread.CurrentThread.CurrentUICulture;
    return taskFactory.StartNew(
        () =>
        {
            Thread.CurrentThread.CurrentCulture = currentCulture;
            Thread.CurrentThread.CurrentUICulture = currentUICulture;
            return function();
        }, cancellationToken, creationOptions, TaskScheduler.Default);
}
public static Task StartNewWithPersistedCulture(
    this TaskFactory taskFactory, Action action, CancellationToken cancellationToken = default (CancellationToken), TaskCreationOptions creationOptions = default (TaskCreationOptions))
{
    if (taskFactory == null) throw new ArgumentNullException("taskFactory");
    if (action == null) throw new ArgumentNullException("action");
    var currentCulture = Thread.CurrentThread.CurrentCulture;
    var currentUICulture = Thread.CurrentThread.CurrentUICulture;
    return taskFactory.StartNew(
        () =>
        {
            Thread.CurrentThread.CurrentCulture = currentCulture;
            Thread.CurrentThread.CurrentUICulture = currentUICulture;
            action();
        }, cancellationToken, creationOptions, TaskScheduler.Default);
} 
#endregion