2010-03-05 19 views
19

Me gustaría establecer la cultura de toda mi aplicación. He intentado lo siguiente:C# Cultura de BackgroundWorker

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture); 
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(wantedCulture); 
Application.CurrentCulture = CultureInfo.CreateSpecificCulture(wantedCulture); 

Funciona para el subproceso actual, pero más tarde me cree e inicie un subproceso de trabajo de fondo. Cuando creo el trabajador, el hilo actual se ejecuta con wantedCulture pero el hilo de trabajo se ejecutará con la cultura de mi computadora.

¿Alguna idea para establecer la cultura de toda la aplicación?

Respuesta

34

NOTA: El material anticuado, asegúrese de leer la actualización en la parte inferior de los cambios en .NET 4.6

Sí, este es un campo común solicitar pero no está disponible. Windows siempre inicializa un subproceso del sistema operativo al sistema LCID predeterminado, configurado en el subprograma de Opciones regionales y de idioma en el Panel de control. Puede anular esto siempre que cree los hilos usted mismo. Pero eso no es práctico para los subprocesos de subprocesos y subprocesos que podrían haber sido creados por algún tipo de código no administrado ejecutando su proceso, como un servidor COM.

El último caso es el problema. .NET no tiene problemas para ejecutar código administrado en subprocesos creados por código no administrado. Pero no puede hacer nada sobre la forma en que se inicializa el hilo. Eso es cierto para CurrentUICulture pero también para cosas más oscuras como Thread.SetApartmentState(). No subestime la probabilidad de que dicho hilo ejecute código en su programa, los servidores COM escritos por Microsoft son muy ingeniosos.

Tendrá que revisar su código con un peine de dientes finos y encontrar cualquier código que pueda ejecutarse en un hilo que no haya creado. Cualquier controlador de eventos es sospechoso, al igual que cualquier método BeginXxx() que tenga una devolución de llamada. BackgroundWorker es definitivamente el problema menor.

No invalidar la cultura del hilo puede producir muy sutil y difícil de diagnosticar bugz. Un buen ejemplo sería una SortedList que teclea una cadena. Cuando se ejecuta con la cultura incorrecta, al azar no podrá encontrar los elementos que están realmente presentes en la lista. Causado por la lista que ya no se ordena en otra cultura con diferentes reglas de intercalación.

Si logré asustarlo lo suficiente, hice llegar mi mensaje. Esto me pasó a mí, solucionando un problema con un programa muy grande que se comportaba mal en una máquina danesa. No teníamos una localización danesa y obligamos a la IU a funcionar en inglés. Un hilo de trabajo usó un árbol rojo-negro que tenía una cuerda como clave. Falló al azar cuando se le pidió que tratara con Åårdvårks. Me tomó una semana.


Actualización: este problema se ha solucionado en .NET 4.5. La clase CultureInfo ahora tiene un DefaultThreadCurrentCulture y DefaultThreadCurrentUICulture. Cuando se establece, se usará para inicializar la cultura de cualquier cadena administrada en lugar de la cultura predeterminada del sistema de Windows.Exactamente cómo interactúa con los hilos que se iniciaron con el código nativo y que ingresan el código administrado aún no está claro para mí.


Actualización: este problema tenía una solución más completa en .NET 4.6. La cultura ahora fluye automáticamente, el comportamiento ideal. El artículo de MSDN para CultureInfo.CurrentCulture() habla de ello. La información proporcionada es aún confusa, experimentalmente también parece fluir a un objeto Thread y no solo a una tarea o subproceso de subprocesos y DefaultThreadCurrentCulture no se utiliza. Dos pasos hacia adelante, un paso atrás, se recomiendan las pruebas.

1

Mi solución era tener una propiedad de cultura central (Application.CurrentCulture es por subproceso) y establecer el cultivo de subprocesos actual en esto al comienzo de un subproceso de trabajador. Un sistema de trabajo ayuda con esto, ya que luego puede ejecutar fácilmente código genérico antes y después del elemento de trabajo, y la clase del sistema de trabajos puede mantener el cultivo accesible para sus trabajos, por lo que no necesita valores globales.

0

No puede hacer esto para cada subproceso recién creado. Deberías hacerlo a mano (¡pero no creo que sea una buena idea crear cultura para los hilos del grupo de subprocesos!). Es posible que su aplicación debe depende de Application.CurrentCulture o algunas otras cosas mundial ..

1

En pocas palabras; No lo hagas.

No haga ningún formato específico de cultivo en ningún otro hilo que el hilo principal (Thread.CurrentThread). Obtener la cultura correcta en otros hilos, cada otro hilo creado, es solo un problema y, tarde o temprano, olvidará configurarlo correctamente. Es mejor evitar el dolor en conjunto y solo hacer un formato cultural específico, convertir, etc., en el hilo que se garantiza que tiene la configuración de cultivo correcta.

0

Windows siempre inicializa una hebra de OS a la LCID por defecto del sistema, configurado en el subprograma regional y de idioma en el Panel de Control de .

Desafortunadamente puedo estar de acuerdo con esto y han encontrado lo contrario.

El sistema se instaló como inglés de EE. UU. Fuimos al panel de control y todo se cambió a danés y se copió en todas las cuentas. Reiniciado.

Ejecute la aplicación de consola que se ejecuta en danés. Ejecuta la aplicación web pregunta al navegador dice danés. Lanza el hilo desde la aplicación web y se inicia como no estadounidense y no puedo entender por qué.

0

Sé que el tema es antiguo, pero me encontré en un problema de "thread with OS culture".

Lo resolví así: como el BackgroundWorker está en un UserControl (sería válido si está en un Formulario y así sucesivamente ...) configuré un campo en el UserControl (o Formulario) cuando se construye. En el controlador de eventos DoWork, uso este campo en mis operaciones. Aquí el código:

/// <summary> 
    /// Culture in which the GUI creates the control. 
    /// </summary> 
    private readonly CultureInfo _currentCulture; 

    /// <summary> 
    ///  Default constructor. 
    /// </summary> 
    public MyControl() 
    { 
     InitializeComponent(); 
     _currentCulture = CultureInfo.CurrentUICulture; 
    } 

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     ExampleClass.DoCultureDependentOperation(_currentCulture); 
    }