Question

Notre produit contient un système de gestion des tâches qui permet aux applications d'exécuter du code dans une DLL selon un intervalle planifié, spécifie des règles indiquant si un échec de la tâche doit désactiver l'application associée, etc. Il est principalement utilisé pour le téléchargement de données. téléchargement de données, maintenance de la base de données locale, etc. Une des fonctions utilisées est de synchroniser l'heure des périphériques via NTP et de définir les informations de fuseau horaire du système d'exploitation. Pour cela, nous utilisons la classe DateTimeHelper d’OpenNetCF, qui semble servir de wrapper autour de Win32 P / Invokes.

L'une des autres fonctionnalités du gestionnaire de tâches est que, si une tâche est exécutée plus longtemps que sa fenêtre de temps ne lui est allouée, le gestionnaire de tâches l'autorisera à Thread.Abort () afin de permettre l'exécution d'autres tâches. Nous constatons un nombre alarmant d'avortements de thread dans lesquels la fonction la plus élevée de la pile est OpenNetCF.WindowsCE.NativeMethods.SetTimeZoneInformation (). Pourquoi le P / Invoke (SetTimeZoneInfo) sous-jacent se bloque-t-il si longtemps?

Notre code fonctionne sous Windows CE 4.2, et avec une base utilisateur beaucoup plus petite, sous Windows CE 5.0 - le code ici est le même entre les deux versions. Jusqu'ici, j'ai vu cela se produire sur des appareils 4.2 mais jamais sur 5.0, et même avec le petit nombre d'utilisateurs sur 5.0, je pense que je l'aurais vu s'il avait été présent là-bas.

La fonction ci-dessous est la fonction à l'origine du problème. Il convertit une abréviation de fuseau horaire en son nom complet, puis utilise ce nom pour rechercher le fuseau horaire approprié et tente de définir le fuseau horaire actuel du périphérique sur celui-là.

        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;
        }

Merci comme toujours pour votre aide. Des pensées?

Était-ce utile?

La solution

L'appel DateTimeHelper.SetTimeZoneInformation est un très mince wrapper autour d'un P / Invoke dans API SetTimezoneInformation (je viens de vérifier cela dans le source). En gros, il passe l’appel et vérifie le code de retour - rien de plus, de sorte que le SDF lui-même n’est pas considéré comme la cause première du problème.

Ensuite, consultez le le document MSDN pour SetTimezoneInformation . un appel synchrone vraiment simple qui renvoie VRAI ou FAUX. Cela me dit que l'API n'est probablement pas la cause première non plus.

Une chose à retenir dans CE est que vous ne pouvez jamais supposer que la plate-forme est parfaite car elle est réalisée par le fabricant OEM et peut donc comporter des variantes. Le fait que vous voyiez la défaillance en 4.2 et non en 5.0 me conduirait à vérifier ce qui suit:

  1. Assurez-vous que tous les QFE sont appliqués dans l'image du périphérique 4.2
  2. Vérifiez s'il existe une différence de code de système d'exploitation entre 4.2 et 5.0 pour le fuseau horaire (j'en doute, mais PB 4.2 n'est plus installé).
  3. Vérifiez la mise en œuvre OEM pour l'heure de réglage. La modification de la zone implique implicitement un appel pour définir l'heure. Il est donc possible qu'un bogue dans le BSP 4.2 présente un verrou potentiel ou une course que vous frappez.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top