2010-07-21 11 views
11

Ho un'applicazione multi-thread che analizza del testo e ha bisogno di usare English Culture Info per analizzare i numeri da questo testo. Quindi, non voglio creare EngCulture ogni volta che chiamo la funzione di analisi. Attualmente sto passando a EngCulture come parametro, ma non ne sono felice. Voglio definire l'EngCulture come membro statico, quindi sarà condiviso dai thread.CultureInfo thread safety

La documentazione di Msdn dice che "Qualsiasi membro statico pubblico (Condiviso in Visual Basic) di questo tipo è thread-safe.Tutti i membri dell'istanza non sono garantiti come thread-safe." Sto semplicemente usando la seguente funzione, quindi come potrei sapere se TryParse usa o meno membri di un'istanza di EngCulture?

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

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

risposta

6

Prova a utilizzare CultureInfo.GetCultureInfo("en-US") che "recupera un'istanza memorizzata nella cache di sola lettura di una cultura utilizzando il nome di cultura specificato."

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

o rendere il vostro campo per essere di sola lettura in modo da non avere bisogno di una serratura:

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

Sì, la promessa readonly lo rende thread-safe. –

+2

Does 'CultureInfo.ReadOnly' garantisce garanzie sulla sicurezza dei thread? Perché [read-only e threadsafe sono diversi] (http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx). –

+0

@ ta.speot.is: Ottima domanda. Ne ero curioso e [ho fatto una domanda a riguardo] (http://stackoverflow.com/q/36766649/87698). – Heinzi

0

"Membri" indica metodi più operatori più campi più proprietà. Stai usando un membro di istanza e quindi dovresti usare un lock o trovare un modo alternativo per farlo.

Spero che questo aiuti!

0

due punti:

non voglio creare EngCulture ogni volta che io chiamo la funzione di parsing

non credo che questo sarebbe in realtà essere troppo di una preoccupazione - CultureInfo s aren Saranno particolarmente grandi, e per quanto riguarda le prestazioni, i "built-in" sono in realtà memorizzati nella cache, quindi tutto ciò che fa un new è recuperare un oggetto esistente. Con tutti i mezzi profilo e vedere se è effettivamente un problema ...

come potrei sapere se TryParse utilizza membri di qualsiasi istanza di EngCulture o no?

sarei estremamente sorpreso di scoprire un metodo che accettato un CultureInfo e poi siamo andati a cambiamento che CultureInfo in alcun modo. Sebbene non siano effettivamente formalmente immutabili, li userei (specialmente quelli "integrati") come se fossero immutabili, senza pensarci due volte.

Quindi, direi avere un new CultureInfo("en-US", false) statico e passarlo in giro - nulla sta per mutarlo, quindi non sorgono problemi multi-threading.

+0

sto esitando che qualche thread lo metterà in uno stato incoerente (nel mezzo della lettura da una lista ecc.) Mentre un altro cerca di leggerlo. quindi, se leggere da esso non era una grande preoccupazione, perché hanno detto che non è sicuro usare membri di istanza. – lockedscope

+0

@lockedscope Apprezzo la tua attenzione. Apprendo da altre risposte che i "built-in" di CultureInfo sono di sola lettura, e in ogni caso c'è un metodo 'ReadOnly', quindi uno di questi approcci dovrebbe garantire la sicurezza. – AakashM

3

Al fine di ottenere thread-sicurezza è possibile creare una cultura di sola lettura utilizzando la statica CultureInfo.ReadOnly metodo:

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

Non riesco a trovare nella documentazione in cui un 'CultureInfo' di sola lettura è thread-safe. Vedi il mio commento sulla risposta accettata. –

1

È possibile impostare il CultureInfo di un thread specifico con System.Threading.Thread.CurrentThread.CurrentCulture = myCI; in modo da n devi passarlo ogni volta che chiami una funzione.

Si noti che l'accesso ai getter da più thread non causerà alcun danno nella maggior parte dei casi se non si modifica l'oggetto.