Почему в Windows CE .NET 4.2 может зависнуть SetTimeZoneInfo?

Наш продукт содержит систему диспетчера задач, которая позволяет приложениям запускать код в DLL через заданный интервал времени, указывать правила о том, должен ли сбой задачи отключать соответствующее приложение и т. д. В основном он используется для загрузки данных, загрузки данных. , обслуживание локальной базы данных и т. д. Одной из используемых функций является синхронизация времени устройств через NTP и установка информации о часовом поясе ОС. Для этого мы используем класс OpenNetCF DateTimeHelper, который, кажется, служит оболочкой для 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;
        }

Как всегда, спасибо за помощь. Есть предположения?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 393
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

  1. Убедитесь, что к образу устройства 4.2 применены все QFE.
  2. Посмотрите, есть ли разница в коде ОС между 4.2 и 5.0 для часового пояса (я сомневаюсь, но у меня больше не установлен PB 4.2).
  3. Проверьте OEM-реализацию установки времени. Изменение зоны неявно вызывает вызов для установки времени, и возможно, есть ошибка в 4.2 BSP, которая имеет потенциальную блокировку или гонку, в которую вы попадаете.

Посмотрев на SDF DLL в отражателе, я понял, что это не на самом деле причина, но поставил «opennetcf» в качестве тега, чтобы получить ваш комментарий. = P Я попробую три пункта ниже, но код для SetTimeZoneInfo, похоже, не является частью общего источника (если я не неправильно понял ...) Спасибо!

RJ Cantrell 05.01.2009 21:43

Другие вопросы по теме