Ich erstelle einen Windows-Dienst, der mehrere Threads ausführt. Kann ich die Kultur meiner gesamten appDomain festlegen, anstatt sie für jeden Thread einzeln festzulegen?Kultur für ganze App-Domäne definieren
Antwort
Dieses nicht ist möglich. Threads erhalten ihre Standardkultur, wenn Windows den Thread erstellt, der aus dem Systemstandardgebietsschema initialisiert wurde, wie es in Systemsteuerung + Region und Sprache konfiguriert wurde. Die relevanten Win32-API-Funktionen sind Get/SetThreadLocale().
Es gibt keinen Mechanismus in der CLR, um einen Thread mit einem anderen Standard zu versehen. Ein häufiges Szenario für einen Thread besteht darin, das Leben aus nicht verwaltetem Code zu starten und viele dieser nicht verwalteten Codes auszuführen und gelegentlich einen Rückruf in verwalteten Code durchzuführen. Dieser verwaltete Code wird mit dem Thread.CurrentCulture-Satz für die vom nicht verwalteten Code ausgewählte Kultur ausgeführt. Oder der Windows-Standard, wenn der nicht verwaltete Code SetThreadLocale() nicht aufgerufen hat. Wenn die CLR geändert wird, führt dies zu einem nicht mehr zu diagnostizierenden Fehler im nicht verwalteten Code.
Natürlich können Sie es explizit überschreiben, aber das ist schwierig zu bekommen. Die feinen Formatierungsfehler sind leicht zu sehen, es wird schwierig, wenn Sie beispielsweise Datenstrukturen verwenden, die implizit auf die Sortierfolge von string angewiesen sind. Eine SortedList kann plötzlich kein Element in der tatsächlich vorhandenen Liste finden. Controlling ist es auch schwer, viele kleine Thread-Thread-Callbacks im gesamten .NET-Framework.
Machen Sie sich nicht damit herum, um nicht in solche Fallen zu geraten, verlassen Sie sich entweder auf den Systemstandard oder wenden Sie CultureInfo explizit an.
UPDATE: wie von Thomas erwähnt, wird eine Lösung in .NET 4.5 verfügbar sein, ist es eine neue Eigenschaft für die Klasse Culture bietet die Appdomain der Standardkultur zu setzen. MSDN-Dokumentation are here. Die genaue Interaktion mit nicht verwalteten Threads, die verwalteten Code eingeben, ist aus der Dokumentation nicht eindeutig. Überprüfen Sie dies, wenn Sie nativen Code Callbacks zulassen, z. B. durch pinvoke, Marshal.GetFunctionPointerForDelegate() oder das Ereignis eines COM-Objekts.
UPDATE2: dies geändert wurde wieder in .NET 4.6, Kultur fließt nun von einem Thread zu einem anderen, so dass die übelsten Ausfallmodi gesorgt. Lesen Sie die Details dazu im MSDN-Artikel für CultureInfo.CurrentCulture. Sie müssen explizit auf 4.6 zielen, um den Vorteil zu erhalten.
Sie könnten eine eigene Methode haben, die Fäden und setzen Kultur automatisch ausgelöst wird:
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);
}
Und wenn Sie einen neuen Thread einfach diese Methode starten müssen verwenden:
StartThread(state => { /** Do some processing on a new thread **/ }, null);
Nizza Lösung ... aber es das Ziel verfehlen - ich brauche etwas, das eingestellt wird die Kultur, auch wenn ich vergesse, sie einzustellen. Dasselbe kann hier passieren, wenn ich vergesse, den Thread durch die Methode 'StartThread' zu starten. Ich möchte, dass alle Threads ihre Kultur automatisch erben – Nissim
Genau. Kannst du mir den Ausschnitt dafür zeigen? – Nissim
Für 4.5 Standard-App Domain Kulturen könnte über CultureInfo
Klasse eingestellt werden:
Dies ist die neue richtige Antwort. – Gleno
Laut [dieser Seite] (http://msdn.microsoft.com/en-us/library/ms171868%28v=vs.110%29.aspx), wird es in .NET 4.5 möglich sein: "Fähigkeit, die Kultur für eine Anwendungsdomäne zu definieren". Allerdings habe ich nicht gefunden, wie es geht ... Ich kann keine relevante Eigenschaft in AppDomain oder AppDomainSetup sehen –
@Thomas: siehe Valdis '[Antwort] (http://Stackoverflow.com/a/8030336/107604) unten. –