2010-11-14 11 views
7

Mi sembra una strana scelta di progettazione che l'attuale informazione sulla cultura (CurrentCulture e/o CurrentUICulture) sia una proprietà del thread in esecuzione. Per lo meno sembra che la portata di una cosa del genere dovrebbe essere un livello superiore, a livello di processo.Perché CurrentCulture è una proprietà di Thread?

Ma queste cose di solito hanno senso quando si sente la logica. Potrebbe essere illuminante scoprire perché i progettisti .NET hanno deciso che Thread era il posto giusto per inserire questa proprietà.

risposta

10

Per i principianti, non era proprio la loro scelta. Quella decisione è stata presa molto tempo prima che iniziassero, la cultura è una proprietà di un thread del sistema operativo. Esaminare i documenti SDK per le funzioni API Get/SetThreadLocale() ad esempio.

Questo non lo spiega completamente, hanno virtualizzato altre funzionalità del sistema operativo, anche se questo è molto difficile da virtualizzare perché molte API sono sensibili alla cultura, in particolare quelle COM.

La prossima buona ragione è che cambiare il processo di cultura in tutto il mondo è estremamente difficile da implementare. È una condizione di gara irrisolvibile. Qualche altro thread potrebbe essere nel bel mezzo di dati di formattazione con affinità culturale. Mentre un blocco funzionerebbe per impedirgli di utilizzare le proprietà della cultura così come sta cambiando, può non impedirgli di cambiare nel mezzo di una catena di chiamate di formattazione. Richiederebbe loro di prendere una sorta di blocco globale e tenerlo premuto per tutta la durata del processo di formattazione. Deadlock è molto probabilmente.

C'è un altro aspetto in questo, uno che penso sia il vero problema. È correlato alla proprietà Thread.ExecutionContext. Il framework usa questo per "fluire" lo stato del thread da un thread all'altro. Molto oscuro ma importante per infondere cose come il contesto di sicurezza su un thread di lavoro. Sarebbe stato ideale se quel contesto fosse anche in grado di impregnare la cultura in modo da poter essere sicuro che tutti i lavoratori che inizi avessero la stessa cultura selezionata e non il default del sistema operativo.

Non è vero, non so davvero perché. Probabilmente perché il primo motivo che ho dato. Che compia, tuttavia, è molto pericoloso cambiare la cultura di un thread. Il tipo di bug che possono causare sono molto sottile. Come creare un SortedDictionary con una stringa come chiave nel thread principale con una cultura predefinita del sistema non operativo. Quindi scoprire che un thread di lavoro non può trovare occasionalmente di nuovo le cose perché le regole di ordinamento delle stringhe sono diverse.


EDIT: c'è qualche sollievo da questo problema in .NET 4.5, supporta il nuovo CultureInfo.DefaultThreadCurrentCulture statica e proprietà DefaultThreadCurrentUICulture.


EDIT2: la cultura ora scorre come descritto nel 4 ° paragrafo in .NET 4.6. Questo dovrebbe alleviare tutte le preoccupazioni.

2

Le maniglie delle finestre sono esse stesse specifiche del filetto. Non utilizzare mai un handle di finestra (per una finestra di livello superiore, un controllo figlio ecc.) Nel contesto di un thread diverso perché il codice che implementa la gestione della finestra (GDI) non è thread-safe. Dato che UICulture è specifico per una finestra, significa che viene definito anche a livello di thread.

Altri aspetti della GUI sono anche specifici del thread, come la finestra attiva e lo stato attivo. Sebbene esista un'API, non riesco a ricordare il nome, che unisce il contesto dell'interfaccia utente da diversi thread insieme in modo che l'attivazione, la finestra attiva sia condivisa tra più thread dell'interfaccia utente.

6

Farò un tentativo, forse perché avresti bisogno di più thread simultanei utilizzando culture diverse? Se pensi a un sito web multilingue asp.net, non vuoi che il processo sia legato a una lingua ... una richiesta web potrebbe essere EN-US e un'altra FR-FR.

2

CurrentCulture non è altro che un riferimento a CultureInfo, quindi non si perderebbe molto lasciandolo appeso al thread (solo la memoria per un riferimento). Allo stesso tempo, si ha la possibilità di consentire agli utenti di controllare con precisione la cultura corrente per thread, che risulta essere importante in alcuni tipi di applicazioni.

Uno dei motivi per cui avere questa grana fine potrebbe essere più ovvio per utenti che non parlano inglese del software moderno. Io per primo devo regolare regolarmente la tastiera in Windows e sono in grado di farlo facilmente con una scorciatoia da tastiera globale. Avere il CultureInfo sul thread ci consente di implementare facilmente una logica simile nelle nostre app .NET senza dover modificare tali informazioni per processo.

esempi di utilizzo che vengono in mente:

  1. potrei desiderare una scorciatoia che avrebbe cambiato la cultura nel mio programma per un breve periodo di tempo, su richiesta per l'utente corrente (molte applicazioni dovrebbero permettere diversi utenti sulla stessa workstation e nella stessa sessione). Ma lo stesso processo potrebbe dover continuare a utilizzare il CultureInfo predefinito sulla macchina, ad es. accedi sempre con lo stesso formato di timestamp.

  2. Si potrebbe anche disporre di una soluzione di report in grado di scaricare report per diversi rami di un'azienda globale, ciascuno nella propria cultura. Il tuo design sarebbe meno vincolato se tu potessi cambiare CultureInfo per thread.

  3. Un altro motivo potrebbe essere se si desidera scrivere su un file utilizzando una particolare cultura, ma non si vorrebbe specificare la cultura nelle funzioni di scrittura (ad esempio perché tali funzioni sono già state scritte). Quindi sei in grado di cambiare facilmente quella logica senza cambiarla su altri thread che potrebbero svolgere attività che richiedono la cultura predefinita.

Problemi correlati