CultureInfo thread safety
Asked Answered
O

5

11

I have a multi-threaded application which parses some text and it needs to use English Culture Info for parsing numbers from this text. So, i do not want to create EngCulture everytime i call the parsing function. Currently i am passing EngCulture as a parameter but i am not happy with this. I want to define the EngCulture as a static member so it will be shared by threads.

Msdn documentation says that "Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe." I am just using the following function, so how could i know whether TryParse uses any instance members of the EngCulture or not?

public static CultureInfo EngCulture = new CultureInfo("en-US", false);

void parser()
{
    if (int.TryParse(value, NumberStyles.Number, EngCulture, out num))...
}
Orlov answered 21/7, 2010 at 11:2 Comment(0)
H
7

Try to use CultureInfo.GetCultureInfo("en-US") that "retrieves a cached, read-only instance of a culture using the specified culture name."

http://msdn.microsoft.com/en-us/library/yck8b540.aspx

or make your field to be readonly so you will not need a lock:

private static CultureInfo _culture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
Hanaper answered 21/7, 2010 at 11:14 Comment(2)
Does CultureInfo.ReadOnly grant thread safety guarantees? Because read-only and threadsafe are different.Tabret
@ta.speot.is: Great question. I was curious about that myself and asked a question about it.Corticate
T
3

In order to get thread-safety you can create a read-only culture using the static CultureInfo.ReadOnly method:

public static CultureInfo EngCulture = CultureInfo.ReadOnly(
    new CultureInfo("en-US", false));
Turnstone answered 21/7, 2010 at 11:14 Comment(1)
I can't find in the documentation where a read-only CultureInfo is thread safe. See my comment on the accepted answer.Tabret
M
1

You can set the CultureInfo of a specific Thread with System.Threading.Thread.CurrentThread.CurrentCulture = myCI; so you do not have to pass it every time you call a function.

Note that just accessing getters from multiple threads won't do any harm in most cases if you do not modify the object.

Marlow answered 21/7, 2010 at 11:16 Comment(0)
K
0

"Members" means methods plus operators plus fields plus properties. You are using an instance member and so should use a lock or find an alternative way of doing this.

Hope that helps!

Khalkha answered 21/7, 2010 at 11:10 Comment(0)
B
0

Two points:

i do not want to create EngCulture everytime i call the parsing function

I don't think this would actually be too much of a concern - CultureInfos aren't going to be especially large, and as for performance, the 'built-in' ones are actually cached, so all a new does is retrieve an existing object. By all means profile and see if it is actually a problem...

how could i know whether TryParse uses any instance members of the EngCulture or not?

I'd be extremely surprised to discover a method that accepted a CultureInfo and then went on to change that CultureInfo in any way. Although they aren't actually formally immutable, I would use them (especially the 'built-in' ones) as if they were immutable, without a second thought.

So, I would say have a static new CultureInfo("en-US", false) and pass it around - nothing is going to mutate it, so multi-threading issues don't arise.

Bechler answered 21/7, 2010 at 11:12 Comment(2)
i am hesitating that some thread will put it in an inconsistent state(in the middle of reading from a list etc.) while another one tries to read it. so, if reading from it was not a big concern why did they say that its not safe to use instance members.Orlov
@Orlov I applaud your caution. I learn from other answers that the 'built-in' CultureInfos are read-only, and in any case there is a ReadOnly method, so one of those approaches should ensure safety.Bechler

© 2022 - 2024 — McMap. All rights reserved.