我们的产品包含一个任务管理器系统,允许应用程序在计划的时间间隔内运行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; }
一如既往地感谢您的帮助。有什么想法吗?
答案 0 :(得分:1)
DateTimeHelper.SetTimeZoneInformation调用是围绕P {Invoke到SetTimezoneInformation API的一个非常薄的包装器(我刚刚在源代码中验证了它)。它基本上会调用并检查返回代码 - 仅此而已,因此几乎排除了SDF本身作为根本原因。
接下来,查看MSDN doc for SetTimezoneInformation,这是一个非常简单的同步调用,返回TRUE或FALSE。这告诉我API也可能不是根本原因。
在CE中要记住的一件事是,你可以从不假设平台是完美的,因为它由OEM完成,因此可以有变化。你在4.2而不是5.0中看到失败的事实会让我检查以下内容: