Domanda

Il nostro prodotto contiene un sistema di gestione delle attività che consente alle applicazioni di eseguire il codice in una DLL a intervalli programmati, di specificare le regole per stabilire se un errore dell'attività deve disabilitare l'applicazione correlata, ecc. Principalmente viene utilizzato per il caricamento dei dati, download dei dati, manutenzione del database locale, ecc. Una delle funzioni utilizzate è la sincronizzazione dell'ora dei dispositivi tramite NTP e l'impostazione delle informazioni sul fuso orario del sistema operativo. Per questo, usiamo la classe DateTimeHelper di OpenNetCF, che sembra fungere da wrapper per Win32 P / Invokes.

Una delle altre funzionalità del task manager è che se un'attività viene eseguita più a lungo della finestra temporale assegnata, il task manager eseguirà Thread.Abort () per consentire l'esecuzione di altre attività. Stiamo vedendo un numero allarmante di aborti di thread in cui la funzione più alta nello stack è OpenNetCF.WindowsCE.NativeMethods.SetTimeZoneInformation (). Perché il P / Invoke sottostante (SetTimeZoneInfo) si bloccherebbe per così tanto tempo?

Il nostro codice funziona su Windows CE 4.2 e, con una base utente molto più piccola, su Windows CE 5.0: il codice qui è lo stesso tra le due versioni. Finora, l'ho visto accadere su dispositivi 4.2 ma mai su 5.0, e anche con il minor numero di utenti su 5.0, penso che l'avrei visto se fosse stato presente lì.

La seguente funzione è la funzione da cui deriva il problema. Converte l'abbreviazione di un fuso orario nel suo nome completo, quindi utilizza il nome per trovare il fuso orario giusto e tenta di impostare il fuso orario corrente del dispositivo su quello.

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

Grazie come sempre per il tuo aiuto. Qualche pensiero?

È stato utile?

Soluzione

La chiamata DateTimeHelper.SetTimeZoneInformation è un wrapper molto sottile attorno a un P / Invoke al SetTimezoneInformation API (l'ho appena verificato nella fonte). Fondamentalmente effettua la chiamata e controlla il codice di ritorno - niente di più, quindi praticamente esclude SDF stesso come causa principale.

Quindi, guardando il Documento MSDN per SetTimezoneInformation , è una chiamata sincrona davvero semplice che restituisce VERO o FALSO. Questo mi dice che probabilmente anche l'API non è la causa principale.

Una cosa da ricordare in CE è che non si può mai supporre che la piattaforma sia impeccabile poiché è realizzata dall'OEM e quindi può presentare variazioni. Il fatto che visualizzi l'errore in 4.2 e non in 5.0 mi porta a verificare quanto segue:

  1. Assicurati che all'immagine del dispositivo 4.2 siano applicati tutti i QFE
  2. Verifica se esiste una differenza di codice del sistema operativo tra 4.2 e 5.0 per il fuso orario (ne dubito, ma non ho più PB 4.2 installato).
  3. Controlla l'implementazione OEM per il tempo di impostazione. Cambiare la zona implicitamente fa una chiamata per impostare l'ora ed è possibile che ci sia un bug nel 4.2 BSP che ha un potenziale blocco o corsa che stai colpendo.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top