Наш продукт содержит систему диспетчера задач, которая позволяет приложениям запускать код в 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;
}
Как всегда, спасибо за помощь. Есть предположения?





Вызов DateTimeHelper.SetTimeZoneInformation - это очень тонкая оболочка вокруг P / Invoke для SetTimezoneInformation API (я только что проверил это в источнике). По сути, он выполняет вызов и проверяет код возврата - не более того, так что в значительной степени исключает сам SDF как основную причину.
Затем, глядя на Документ MSDN для SetTimezoneInformation, это действительно простой синхронный вызов, который возвращает TRUE или FALSE. Это говорит мне о том, что API, вероятно, тоже не является основной причиной.
Одна вещь, о которой следует помнить в CE, заключается в том, что вы можете никогда предполагать, что платформа безупречна, потому что это делает OEM и, следовательно, может иметь вариации. Тот факт, что вы видите сбой в 4.2, а не в 5.0, заставил бы меня проверить следующее:
Посмотрев на SDF DLL в отражателе, я понял, что это не на самом деле причина, но поставил «opennetcf» в качестве тега, чтобы получить ваш комментарий. = P Я попробую три пункта ниже, но код для SetTimeZoneInfo, похоже, не является частью общего источника (если я не неправильно понял ...) Спасибо!