Вопрос

Наш продукт содержит систему диспетчера задач, которая позволяет приложениям запускать код в DLL через запланированный интервал, указывать правила о том, должен ли сбой задачи отключать связанное приложение, и т. д. В основном он используется для загрузки данных, загрузка данных, обслуживание локальной базы данных и т. д. Одна из используемых функций заключается в синхронизации времени устройств через NTP и установке информации о часовом поясе ОС. Для этого мы используем класс DateTimeHelper в OpenNetCF, который, похоже, служит оболочкой для Win32 P / Invokes.

Одной из других функций диспетчера задач является то, что если задача выполняется дольше, чем ее выделенное временное окно, диспетчер задач запустит Thread.Abort (), чтобы разрешить выполнение других задач. Мы видим тревожное число прерываний потока, в которых самая высокая функция в стеке - OpenNetCF.WindowsCE.NativeMethods.SetTimeZoneInformation (). Почему базовый P / Invoke (SetTimeZoneInfo) зависает так долго?

Наш код работает в Windows CE 4.2 и с гораздо меньшей пользовательской базой в Windows CE 5.0 - код здесь одинаковый между двумя версиями. До сих пор я видел, что это происходит на устройствах 4.2, но никогда на 5.0, и даже с меньшим количеством пользователей на 5.0, я думаю, я бы видел, если бы он присутствовал там.

Приведенная ниже функция - это функция, из которой вытекает проблема. Он преобразует сокращение часового пояса в его полное имя, затем использует имя для поиска правильного часового пояса и пытается установить текущий часовой пояс устройства на этот.

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

Спасибо как всегда за вашу помощь. Есть мысли?

Это было полезно?

Решение

Вызов DateTimeHelper.SetTimeZoneInformation представляет собой очень тонкую оболочку вокруг P / Invoke для SetTimezoneInformation API (я только что проверил это в источнике). Он в основном выполняет вызов и проверяет код возврата - ничего более, так что в значительной степени исключает сам SDF как основную причину.

Далее, глядя на документ MSDN для SetTimezoneInformation , действительно простой синхронный вызов, который возвращает TRUE или FALSE. Это говорит мне о том, что API, вероятно, также не является основной причиной.

В CE нужно помнить одну вещь: вы никогда не можете предположить, что платформа безупречна, потому что она сделана OEM и поэтому может иметь различные варианты. Тот факт, что вы видите сбой в 4.2, а не 5.0, заставил меня проверить следующее:

<Ол>
  • Убедитесь, что к образу устройства 4.2 применены все QFE
  • Посмотрите, есть ли разница в кодах ОС между 4.2 и 5.0 для часовых поясов (я сомневаюсь в этом, но у меня больше не установлен PB 4.2).
  • Проверьте реализацию OEM для установки времени. Изменение зоны неявно делает вызов, чтобы установить время, и, возможно, в 4.2 BSP есть ошибка, которая имеет потенциальную блокировку или расу, на которую вы попали.
  • Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top