setting culture of threads

G

Guest

I have an application that needs to be able to run in both english & Hebrew.
(Regardless of the culture set in the windows Control Panel).
So I set CurrentThread.CurrentCulture & CurrentThread.CurrentUICulture to
the cutlure I want at the beginning of the program.
Then I found, To my suprise that the threads I create in the application
(and the Thread pool threads) still have the original cultures.
Does this mean that every time I want to use a thread I need to manually set
the CultureInfo at the beginning of the Thread function?
Is there some global setting of the Application that allows me to set the
default CultureInfo of the current instance of the application?
I REALLY would like to avoid having to define some static variable holding
the application culture and use it EVERYWHERE...

Thanks,
Nadav

PS, why is the Culture settings a thread setting?
I would think it will be very confusing if different threads would write to
the GUI but use different Culture settings.
In what cases do we need different cultures in different threads of the same
application?
 
J

Jeffrey Tan[MSFT]

Hi Nadav,

Thanks for your post.

Yes, culture is an execute attribute. In Windows, the execute unit is
thread, not process, so the culture is a property of the executing thread.

When a thread is started, its culture is initially determined by using
GetUserDefaultLCID from the Windows API and its UI culture is initially
determined by using GetUserDefaultUILanguage from the Windows API.

So, the behavior you see is by the design of .Net Framework. The newly
created thread CurrentCulture property's default value is the system's User
Locale, which is set in the Regional Options control panel. The
CurrentUICulture property's default value is the system's UI Language,
which is the language of your system UI. On Windows 2000 and Windows XP
MultiLanguage Edition, the CurrentUICulture defaults to the current user UI
language settings. For more information, please refer to the link below:
"Setting the Culture and UI Culture for Windows Forms Globalization"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/
vbtskcustomizingsettingsforspecificcultures.asp

For your question, there is no application-wide or process-wide setting.
You could store a culture setting in app.config file, and then set each
newly created thread's culture with this setting value. With this approach,
you can manage the application/process wide culture in the app.config file.

Hope this helps!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Hi Jeffrey,

Yes, It helps.
I thought this was the case.
I just wanted to make sure, before I start thinking about How to store the
application wide culture info.
This means that I have to Manually set the culture info for Each thread I use
(including threadpool threads).
What would you do if you had a component (something you didn't write) that
executes some task in some threadpool thread? How would you set it's thread
culture?

Nadav
 
J

Jeffrey Tan[MSFT]

Hi Nadav,

Thanks for your feedback.

For thread pool thread, I do not think there is a way to set the thread
culture before its running. However, we can set its culture information
using the Application.CurrentCulture property in the thread procedure code.

Sample code looks like this:

private void Form1_Load(object sender, System.EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
}

// This thread procedure performs the task.
static void ThreadProc(Object stateInfo)
{
Console.WriteLine(Thread.CurrentThread.CurrentCulture.EnglishName);
Application.CurrentCulture= new CultureInfo("zh-CN");
Console.WriteLine(Thread.CurrentThread.CurrentCulture.EnglishName);
// No state object was passed to QueueUserWorkItem, so
// stateInfo is null.
Console.WriteLine("Hello from the thread pool.");
}
Hope this helps!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Hi Jeffrey,
I know you can set the threadpool thread culture,
But let say I have a component that starts a threadpool thread to perform
processing in the background.
All I supply for it is a delegate that the component calls to report status
(or errors).
The component reads the status text from it's own resources and calls the
delegate supplied by the main application.
In this scenario the Main Application cannot set the threadpool thread
culture before it reads the resource strings.

Now, if I component is mine , I can change it to set the culture of the
thread when it starts.
But this means either passing(or saving) the culture of the thread where the
component is called (i.e. the thread where the component queues the work
item) or saving the culture info of the application in a place where ALL my
components can access (some global variable,in the registry, or something
like this).
Both options are possible, but they don't seem very 'clean'.
But what do I do if I didn't write the component?

Things would have been much easier if you could have overridden the default
CultureInfo of the application.
I.E. The Application has a read/write variable that specifies the default
culture for threads that is set to the culture from the OS, but can be
overriden by the application.

BTW, when a threadpool is recycled - is it's CurrentCulture&CurrentUICulture
reset to the OS culture?

Thanks
Nadav.
 
J

Jeffrey Tan[MSFT]

Hi Nadav,

Thanks for your feedback.

If the thread component is not created by you, I think we have to use a
wrapper method arround it. In this wrapper method, we can first use
Application.CurrentCulture to set the culture, then calls the actual thread
procedure.
I am not sure about this. But I think we'd better set the culture
explicitly when using the thread got from thread pool.

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Hi Jeffrey,
Hi Nadav,

Thanks for your feedback.

If the thread component is not created by you, I think we have to use a
wrapper method arround it. In this wrapper method, we can first use
Application.CurrentCulture to set the culture, then calls the actual thread
procedure.
I'm sure what exactly you mean.
Application.CurrentCulture just gets/sets the CurrentCulture of the
CurrentThread (and the same goes for
System.Globalization.CultureInfo.CurrentCulture).
So I have to have access to the component background thread BEFORE it reads
the strings from the resource. But it will probably call my delegate AFTER it
read the string because it's going to pass it to my delegate).
Let's see an example.

Lets say I've got a component(dll) that performs FTP downloads.
You use it like this:
Ftp ftp=new Ftp(user,pass,host);
ftp.DownloadEvent+=new Ftp.DownloadEventHandler(myEventHandler);
ftp.GetFile(LocalFile,RemoveFile);

void myEventHandler(object sender, Ftp.DownloadEventArgs e) {
if (e.Status==Ftp.DownloadState.ERROR) {
System.Console.WriteLine(e.Details);
}
}

The Ftp component gets the Ftp.DownloadEventArgs.Details string from it's
string resources (using it's internal thread CurrentCulture), and then calls
the DownloadEvent event handler.
I am not sure about this. But I think we'd better set the culture
explicitly when using the thread got from thread pool.
Yes, but again we need to have some standard place to save the CultureInfo
of the Application.
Some place that every project can access.
I would rather not have to create a project that EVERY project of mine that
uses threads&globalization references just so I have a place to store the
application's CultureInfo.

All in All, I think the current design is convinient.
The Execution unit of windows might be the thread, but the user interacts
with the Application as a whole, and I don't there are many cases where you
WANT your threads to have different cultures.

Nadav
 
J

Jeffrey Tan[MSFT]

Hi Nadav,

Yes, I agree with you that there are not many cases where we want threads
to have different cultures. Anyway, if you have any further question,
please feel free to post. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
R

Robin Wang

Hi there,

I have exact the same problem. Following this discussion, I understand that
this is by design. However, I do not think this is a good design. Anyone
disagrees?

If it is not likely that the threads of an application will run in different
culture, what is the purpose to take away the ability to set the culture of
all the threads in one place, or by default, take this setting from the
application? We need the flexibility, you would say. Okay, can we at least
have this option by default? I do think taking the default settings from the
OS for my threads is a terrible design - after all, If I want to run my
application in the OS default culture, I would not have to do anything
specific at all.

The reason I am questioning this design is that I have tons of threads
managed in my application, it kills me to write that 2 lines of code to set
the culture information in the thread delegates. Plus, I do not think this is
a good practice.

So, could this be filed with Microsoft as a bug (I really think it is) or at
least as an enhancement? Who can do this?

Best regards.

Robin Wang
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top