Running a task using CurrentCulture for the creator of the CurrentCulture task

I have an application in which we use Tasks. We also modified cultureInfo (we use the EN-US language, but keep the date / number format), and we use .Net 4.0.

There are many threads and tasks in the application, and we have a factory for creating Task / Threads.

For the thread, we have the following code to ensure that each thread is started with the correct 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 }; } 

But for tasks, I don’t know how to implement such a mechanism:

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

Any idea?

+6
source share
3 answers

I'm not sure if you really need a MonitoredTask for this. You can capture a custom culture using closure:

 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. }); } 

Another way to do this is to pass the current culture as an object state using proper overload (either Action<object> or Func<object, TResult> ):

 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); } 

I would definitely go with the first one.

For more information on closing, see What is a "Close" in .NET?

+4
source

To add more details to @Yuval Itzchakov, I usually create some extension methods for the TaskFactory class that preserve Culture (usually I also add one that receives an action that sets any given property to the executable stream

 #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 
0
source

In .Net 4.5, you can set the default culture for all threads in the current application domain ( MSDN ):

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

Thus, you will have a single culture for all tasks and threads in your application.

0
source

Source: https://habr.com/ru/post/973021/


All Articles