2010-09-13 5 views

Répondre

8

Ce n'est pas possible. Les threads obtiennent leur culture par défaut lorsque Windows crée le thread, initialisé à partir des paramètres régionaux par défaut du système, comme configuré dans Panneau de configuration + Région et langue. Les fonctions pertinentes de l'API Win32 sont Get/SetThreadLocale().

Il n'y a aucun mécanisme dans le CLR pour imbiber un thread avec un autre défaut. Un scénario courant pour un thread est de démarrer la vie créée par du code non géré et d'exécuter beaucoup de ce code non géré, en effectuant parfois un rappel dans le code managé. Ce code géré s'exécutera avec le jeu Thread.CurrentCulture sur la culture sélectionnée par le code non managé. Ou la valeur par défaut de Windows si le code non géré n'a pas appelé SetThreadLocale(). Avoir le CLR changer cela causerait l'échec non-diagnosticable dans le code non managé.

Bien sûr, vous pouvez le remplacer explicitement, mais c'est difficile à obtenir. Les erreurs de formatage subtiles sont assez faciles à voir, cela devient difficile quand vous utilisez, disons, des structures de données qui s'appuient implicitement sur les ordres de chaîne de compilation. Une liste SortedList ne peut soudainement pas retrouver un élément dans la liste réellement présente. Contrôler c'est difficile aussi, beaucoup de petits rappels thread threadpool dans tout le framework .NET. Ne pas déranger avec cela pour éviter de tomber dans des pièges comme ceux-ci, soit s'appuyer sur la valeur par défaut du système ou appliquer le CultureInfo explicitement.


MISE À JOUR: comme l'a noté Thomas, une solution sera disponible en 4.5 .NET, il a une nouvelle propriété pour la classe CultureInfo pour définir la culture par défaut du appdomain. Docs MSDN are here. L'interaction exacte avec les threads non gérés qui entrent dans le code managé n'est pas très claire dans la documentation, assurez-vous de vérifier cela si vous autorisez le code natif à effectuer des rappels, par exemple via pinvoke, Marshal.GetFunctionPointerForDelegate() ou un événement COM.


MAJ2: cela a été changé à nouveau dans .NET 4.6, la culture coule maintenant d'un fil à l'autre de sorte que les plus méchants modes de défaillance sont pris en charge. Lisez les détails à ce sujet dans l'article MSDN pour CultureInfo.CurrentCulture. Vous devez cibler explicitement 4.6 pour obtenir le bénéfice.

+1

Selon [cette page] (http://msdn.microsoft.com/en-us/library/ms171868%28v=vs.110%29.aspx), il sera possible dans .NET 4.5: "Possibilité de définir la culture pour un domaine d'application". Cependant, je n'ai pas trouvé comment le faire ... Je ne vois aucune propriété pertinente dans AppDomain ou AppDomainSetup –

+0

@Thomas: voir Valdis '[answer] (http://stackoverflow.com/a/8030336/107604) au dessous de. –

3

Vous pourriez avoir une méthode personnalisée qui déclenche les discussions et la culture définit automatiquement:

static bool StartThread(WaitCallback callback, object state) 
{ 
    return ThreadPool.QueueUserWorkItem(s => 
    { 
     // Set the culture 
     Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES"); 
     // invoke the callback 
     callback(s); 
    }, state); 
} 

Et quand vous avez besoin pour démarrer un nouveau thread il suffit d'utiliser cette méthode:

StartThread(state => { /** Do some processing on a new thread **/ }, null); 
+0

solution de Nice ... mais manquez la cible - je besoin de quelque chose qui va mettre la culture même quand j'oublie de la mettre. La même chose peut arriver ici si j'oublie de démarrer le thread à travers la méthode 'StartThread'. Je veux que tous les fils héritent automatiquement de leur culture – Nissim

+0

Exactement. Pouvez-vous me montrer l'extrait pour faire cela? – Nissim

Questions connexes