在我们的.CF应用程序中,我们从部分代码中发现了不应该有问题的奇怪错误。例如,下面的代码:WinCE 6.0下.Net CF框架代码中的奇怪例外R3
public void AddParm(string str)
{
string[] pair = str.Split('=');
string key = pair[0].Trim();
string value = pair.Length > 1 ? pair[1] : "";
if (key.Length > 0)
{
if (_parmTable.ContainsKey(key))
_parmTable[key] = value;
else
_parmTable.Add(key, value);
}
}
调用AddParm例程()包装在一个try ... catch块调用,捕获所有异常类型。
public void Unpack(string txn)
{
try
{
// split out strings like: "EVENTLABEL:x=1,y=2,z=3"
char chEvent = ':';
char chSeparator = ',';
_parmTable = new Hashtable();
int iEvent = txn.IndexOf(chEvent);
if (iEvent == -1)
_eventLabel = txn;
else
{
_eventLabel = txn.Substring(0, iEvent);
string parms = txn.Substring(iEvent + 1).TrimEnd('\n');
string[] items = parms.Split(chSeparator);
if (items.Length <= 0)
AddParm(parms);
else
foreach (string item in items)
AddParm(item);
}
}
catch (Exception ex)
{
AppLog.logException(string.Format("UnpackedTask.Unpack: Error parsing '{0}'", txn), ex);
}
}
我刚刚得到一个核心未处理的异常,列出错误模块为mscoree3_5.dll。堆栈跟踪显示:
at ArrayList.InternalSetCapacity(Int32 value, Boolean updateVersion) at ArrayList.EnsureCapacity(Int32 min) at ArrayList.Add(Object value) at String.Split(Char[] separator) at AddParm(String str)
这发生在工作线程上。
我没有注册一个与AppDomain.CurrentDomain.UnhandledException在Main中的处理程序,但它也没有捕获到异常。
不幸的是,出现的WinCE错误对话框没有说明错误的类型或给出错误消息,只是它在mscoree3_5.dll和堆栈跟踪中。
我们创建了由AddParm解析的值,我认为AddParm足够防御,以便在分割调用之前捕获任何潜在问题。由于AddParm被调用的方式,它永远不会被一个空字符串调用。即使我不相信AddParm可能会被无效的东西调用,包装调用的Try ... Catch应该总是捕获异常,但它不会。
同样,我们也看到了未被捕获的错误是这样的:
A native exception has occurred on BbCore.exe At RuntimeType.InternalGetField(rt…) At RuntimeType.InternalGetField(rt…) At SRSupport.GetString() At SRSupport.GetString() At IPAddress.Parse(String ipString)
下面是一个完整的堆栈跟踪今早:
At CurrentSystemTimeZone.GetDaylightChanges(Int32 year) At CurrentSystemTimeZone.GetUtcOffsetFromUniversalTime(DateTime time, Boolean& isAmbiguousLocalDst) At CurrentSystemTimeZone.ToLocalTime(DateTime time) At DateTime.ToLocalTime() At DateTime.get_Now() At MainLoop.timer1_Tick(Object sender, EventArgs e) At Timer._WnProc(WM wm, Int32 wParam, Int32 lParam) At ApplicationThreadContext._InternalContextMessages(WM wm, Int32 wParam, Int32 lParam) At NativeMethods.GetMessage(MSG& lpMsg, IntPtr hWnd, UInt32 wMsgFilterMin, UInt32 wMsgFilterMax) At Application2.Pump() At Application2.RunMessageLoop(Boolean showForm) At Application2.Run(Form mainForm, Boolean runAsSingletonApp, Boolean displayMainForm) At Startup.Main()
的应用2引用是由于使用OpenNetCF.Windows的.Forms.dll。我从来没有在代码的那部分看到崩溃,它基本上是随机的。
这是另一种情况,其中IPAddress.Parse从Try ... Catch中调用,捕获所有Exception类型。在这种情况下,我相信可以用空字符串调用Parse,但我不明白为什么它显示为未处理的异常,甚至没有被我们的未处理的异常处理程序捕获,而是被WindowsCE捕获异常处理程序并导致整个应用程序崩溃。
从R2升级到WinCE 6 R3平台构建器后,看起来这些更为常见。我不确定他们是否曾经在R2下发生过,但他们肯定不太经常。即使现在它们并不总是发生 - 我无法可靠地再现它们。
任何想法?为什么框架的核心部分会抛出不被Try..Catch捕获的错误?
附加信息:看来我忽略了一条重要信息。 ExceptionCode被列为0x80000002,这看起来是一个本机内存不足异常。根据垃圾收集器,我们的应用很少使用超过1MB的内存。根据coredll.dll的GlobalMemoryStatus,系统的典型内存负载约为29%(在57MB中有41MB空间)。那里有没有好的实用程序能够监视和记录整个系统内存的使用情况?我开始怀疑我用来衡量内存使用的技术是否不如我想像的那么精确。使用OpenNetCF.ToolHelp.ProcessEntry。GetProcesses()显示我们的进程使用大约3.6MB和NK.exe使用大约2.5 MB。
您能否包含调用您的“AddParm”方法的代码,以及包含所有细节(以及完整堆栈)的完整异常消息。 – 2010-02-11 18:38:10
我实际上没有足够的堆栈了。上面显示的所有电话都是内部方法。我没有它的原因是因为这个错误来自WinCE并且显示在屏幕上 - 因为它没有被捕获它不会被记录,并且我已经多次尝试重新启动钻井平台来徒劳地尝试获取它再次发生。 – 2010-02-11 20:53:21