Pregunta

Nuestro producto contiene un sistema de administrador de tareas que permite que las aplicaciones ejecuten código en una DLL en un intervalo programado, especifique las reglas sobre si una falla de la tarea debería deshabilitar la aplicación relacionada, etc. descarga de datos, mantenimiento de bases de datos locales, etc. Una de las funciones utilizadas es sincronizar la hora del dispositivo a través de NTP y configurar la información de la zona horaria del SO. Para esto, usamos la clase DateTimeHelper de OpenNetCF, que parece servir como una envoltura alrededor de Win32 P / Invokes.

Una de las otras características del administrador de tareas es que si una tarea se ejecuta más tiempo que la ventana de tiempo asignada, el administrador de tareas creará Thread.Abort () para permitir que se ejecuten otras tareas. Estamos viendo un número alarmante de abortos de subprocesos en los que la función más alta en la pila es OpenNetCF.WindowsCE.NativeMethods.SetTimeZoneInformation (). ¿Por qué el P / Invoke (SetTimeZoneInfo) subyacente se bloquea durante tanto tiempo?

Nuestro código se ejecuta en Windows CE 4.2, y con una base de usuarios mucho más pequeña, en Windows CE 5.0, el código aquí es el mismo entre las dos versiones. Hasta ahora, he visto que esto ocurre en dispositivos 4.2, pero nunca en 5.0, e incluso con un número menor de usuarios en 5.0, creo que lo habría visto si hubiera estado presente allí.

La siguiente función es la función de la que se deriva el problema. Convierte una abreviatura de zona horaria a su nombre completo, luego usa el nombre para encontrar la zona horaria correcta e intenta establecer la zona horaria actual del dispositivo en esa.

        public static bool SetTimeZone(string timeZoneAbbreviation)
        {
            string TimeZoneInfo = string.Empty;
            bool timeZoneChanged = false;

            switch (timeZoneAbbreviation)
            {
                case ALASKA:
                    TimeZoneInfo = ALASKA_TZN;
                    break;
                case ALASKA_ALT:
                    TimeZoneInfo = ALASKA_TZN;
                    break;
                case ATLANTIC:
                    TimeZoneInfo = ATLANTIC_TZN;
                    break;
                case ATLANTIC_ALT:
                    TimeZoneInfo = ATLANTIC_TZN;
                    break;
                case CENTRAL:
                    TimeZoneInfo = CENTRAL_TZN;
                    break;
                case CENTRAL_ALT:
                    TimeZoneInfo = CENTRAL_TZN;
                    break;
                case EASTERN:
                    TimeZoneInfo = EASTERN_TZN;
                    break;
                case INDIANA:
                    TimeZoneInfo = INDIANA_TZN;
                    break;
                case HAWAII:
                    TimeZoneInfo = HAWAII_TZN;
                    break;
                case MOUNTAIN:
                    TimeZoneInfo = MOUNTAIN_TZN;
                    break;
                case ARIZONA:
                    TimeZoneInfo = ARIZONA_TZN;
                    break;
                case PACIFIC:
                    TimeZoneInfo = PACIFIC_TZN;
                    break;
                case PACIFIC_ALT:
                    TimeZoneInfo = PACIFIC_TZN;
                    break;

                default:                    
                    break;
            }

            TimeZoneInfo += "\0";

            TimeZoneCollection tzc = new TimeZoneCollection();
            tzc.Initialize();

            foreach (TimeZoneInformation tzi in tzc)
            {
                string tzDisplayName = tzi.DisplayName.TrimEnd(new char[]{'\\','0'});

                if (tzDisplayName.ToUpper(CultureInfo.CurrentCulture).Equals(TimeZoneInfo.ToUpper(CultureInfo.CurrentCulture)))
                {
                    DateTimeHelper.SetTimeZoneInformation(tzi);
                    System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
                    timeZoneChanged = true;
                    break;
                }
            }

            return timeZoneChanged;
        }

Gracias como siempre por tu ayuda. ¿Algún pensamiento?

¿Fue útil?

Solución

La llamada DateTimeHelper.SetTimeZoneInformation es una envoltura muy delgada alrededor de un P / Invoke al SetTimezoneInformation API (acabo de verificar que en la fuente). Básicamente, realiza la llamada y verifica el código de retorno, nada más, por lo que prácticamente descarta el propio SDF como la causa principal.

A continuación, consulte la MSDN doc para SetTimezoneInformation , es una llamada sincrónica realmente sencilla que devuelve VERDADERO o FALSO. Esto me dice que la API probablemente tampoco sea la causa raíz.

Una cosa a recordar en CE es que nunca puede nunca asumir que la plataforma es impecable, ya que está hecha por el OEM y, por lo tanto, puede tener variaciones. El hecho de que vea la falla en 4.2 y no 5.0 me llevaría a verificar lo siguiente:

  1. Asegúrese de que la imagen del dispositivo 4.2 tenga todas las QFE aplicadas
  2. Vea si hay una diferencia de código de sistema operativo entre 4.2 y 5.0 para las cosas de la zona horaria (lo dudo, pero ya no tengo PB 4.2 instalado).
  3. Verifique la implementación OEM para establecer el tiempo. Cambiar la zona implícitamente hace una llamada para establecer la hora y es posible que haya un error en el BSP 4.2 que tenga un bloqueo o una carrera potencial al que estás golpeando.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top