2010-07-21 8 views
11

Ich habe eine Multi-Threaded-Anwendung, die einige Text analysiert und es benötigt English Culture Info zum Parsen von Zahlen aus diesem Text. Also, ich möchte nicht jedes Mal, wenn ich die Parsing-Funktion aufrufen, EngCulture erstellen. Derzeit übergebe ich EngCulture als Parameter, aber ich bin nicht glücklich damit. Ich möchte die EngCulture als ein statisches Mitglied definieren, so dass es von Threads geteilt wird.CultureInfo Thread Sicherheit

Die Dokumentation von Msdn besagt, dass "alle öffentlichen statischen Member (Shared in Visual Basic) dieses Typs threadsicher sind. Alle Instanzenmitglieder sind nicht garantiert threadsicher." Ich benutze nur die folgende Funktion, also wie könnte ich wissen, ob TryParse Instanz Mitglieder der EngCulture verwendet oder nicht?

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

void parser() 
{ 
    if (int.TryParse(value, NumberStyles.Number, EngCulture, out num))... 
} 

Antwort

6

Versuchen Sie, CultureInfo.GetCultureInfo("en-US") zu verwenden, die eine zwischengespeicherte, schreibgeschützte Instanz einer Kultur unter Verwendung des angegebenen Kulturnamens abrufen.

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

oder machen Sie Ihr Feld nur lesbar zu sein, so dass Sie nicht eine Sperre benötigen:

private static CultureInfo _culture = CultureInfo.ReadOnly(new CultureInfo("en-US")); 
+1

Ja, das readonly Versprechen macht es thread-safe. –

+2

Gewährleistet 'CultureInfo.ReadOnly' Thread-Sicherheitsgarantien? Weil [schreibgeschützt und Threadsafe unterschiedlich sind] (http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx). –

+0

@ ta.speot.is: Große Frage. Ich war selbst neugierig darauf und habe eine Frage dazu gestellt (http://stackoverflow.com/q/36766649/87698). – Heinzi

0

"Mitglieder" bedeutet Methoden plus Operatoren plus Felder plus Eigenschaften. Sie verwenden ein Instanzmitglied und sollten daher eine lock verwenden oder eine andere Möglichkeit finden, dies zu tun.

Hoffe, dass hilft!

0

Zwei Punkte:

ich will nicht EngCulture Jedesmal, wenn ich rufe die Parsing-Funktion

Ich glaube nicht, dass dies wäre eigentlich zu viel von einer Besorgnis schaffen - CultureInfo s aren Es wird nicht besonders groß sein, und was die Leistung anbelangt, werden die 'eingebauten' tatsächlich zwischengespeichert, so dass ein new ein vorhandenes Objekt abruft. Auf jeden Fall Profil und sehen, ob es tatsächlich ein Problem ist ...

Wie könnte ich wissen, ob TryParse verwendet Instanz Mitglieder der EngCulture oder nicht?

Ich würde sehr überrascht sein, ein Verfahren zu entdecken, die akzeptierte eine CultureInfo und fuhr dann fort zu Änderung dass CultureInfo in keiner Weise. Obwohl sie eigentlich nicht formal unveränderlich sind, würde ich sie (besonders die "eingebauten") so verwenden, als wären sie unveränderlich, ohne einen zweiten Gedanken.

Also würde ich sagen, haben Sie eine statische new CultureInfo("en-US", false) und übergeben Sie es herum - nichts wird es mutieren, so entstehen Multithreading-Probleme nicht.

+0

Ich zögere, dass ein Thread es in einen inkonsistenten Zustand versetzt (in der Mitte des Lesens von einer Liste usw.), während ein anderer versucht, es zu lesen. Also, wenn das Lesen davon keine große Sorge war, warum haben sie gesagt, dass es nicht sicher ist, Instanzmitglieder zu verwenden. – lockedscope

+0

@lockedscope ich applaudiere deine Vorsicht. Ich lerne aus anderen Antworten, dass die 'eingebauten' 'CultureInfo's schreibgeschützt sind, und in jedem Fall gibt es eine' ReadOnly'-Methode, also sollte einer dieser Ansätze die Sicherheit gewährleisten. – AakashM

3

Um Thread-Sicherheit bekommen Sie eine Nur-Lese-Kultur mit dem statischen erstellen CultureInfo.ReadOnly Methode:

public static CultureInfo EngCulture = CultureInfo.ReadOnly(
    new CultureInfo("en-US", false)); 
+1

Ich kann in der Dokumentation nicht finden, wo eine schreibgeschützte 'CultureInfo' threadsicher ist. Siehe meinen Kommentar zu der akzeptierten Antwort. –

1

Sie die Culture eines bestimmten Thema einstellen können mit System.Threading.Thread.CurrentThread.CurrentCulture = myCI; so tun Sie n Sie müssen es jedes Mal weitergeben, wenn Sie eine Funktion aufrufen.

Beachten Sie, dass der Zugriff auf Getter aus mehreren Threads in den meisten Fällen keinen Schaden verursacht, wenn Sie das Objekt nicht ändern.