В нашем приложении .Net CF мы получаем странные ошибки из частей кода, которые не должны иметь проблем. Например, следующий код:
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 достаточно защищен, чтобы он мог уловить любые потенциальные проблемы перед вызовом Split. Из-за способа вызова 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()
Ссылки Application2 связаны с использованием OpenNetCF.Windows.Forms.dll. Я никогда не видел сбоев в этой части кода, это в основном случайное.
Это еще один случай, когда IPAddress.Parse вызывается из попытки Try ... Catch, которая перехватывает все типы исключений. В этом случае я считаю, что Parse можно было вызывать с пустой строкой, но я не понимаю, почему он обнаружился как необработанное исключение и даже не попал в наш обработчик необработанного исключения, а вместо этого был пойман WindowsCE обработчик исключений и вызвал сбой всего приложения.
Похоже, что они более распространены, так как мы обновились до сборщика платформ WinCE 6 R3 из R2. Я не уверен, что они когда-либо случались под R2, но они, конечно, были реже. Даже сейчас они не всегда случаются - я не могу их достоверно воспроизвести.
Есть идеи? Почему основные части фреймворка генерируют ошибки, которые не попадают в Try..Catch?
Дополнительная информация: Похоже, я пропустил важную информацию. Код ExceptionCode указан как 0x80000002, который выглядит как собственное исключение из-за нехватки памяти. По словам сборщика мусора, наше приложение редко использует более 1 МБ памяти. Согласно GlobalMemoryStatus coredll.dll типичная загрузка памяти для системы составляет около 29% (41 МБ свободно из 57 МБ). Существуют ли какие-либо полезные утилиты, которые могли бы отслеживать и регистрировать общее использование системной памяти с течением времени? Я начинаю задаваться вопросом, не являются ли методы, которые я использую для измерения использования памяти, не такими точными, как я думал. Использование OpenNetCF.ToolHelp.ProcessEntry.GetProcesses () показывает наш процесс с использованием около 3,6 МБ и NK.exe с использованием около 2,5 МБ.