Как я могу получить полезную информацию (например, трассировки стека) в приложениях С# Windows Store (Metro) при их сбое?
Итак, я делаю первые шаги на С# (и .NET/Visual Studio в целом) и начал писать простую головоломку с черепицей в качестве переносной библиотеки и писать пользовательский интерфейс для разных целевых платформ. Я начал с пользовательского интерфейса консоли и перешел в приложение WPF. Затем я попробовал "Windows Store", и по большей части я мог скопировать код WPF и просто изменить некоторые пространства имен и сигнатуры методов.
Но некоторые вещи ведут себя по-другому, и мне понадобилось более часа поискового запроса, чтобы получить его, чтобы дать мне какую-либо информацию о разбившемся я. Поэтому, если, например, я делаю что-то подобное в обычном приложении WPF:
Storyboard.SetTargetProperty(animation,
new PropertyPath("{Canvas.MispelledProperty}"));
Я получаю исключение .NET в точном месте, где возникает исключение. Если я сделаю ту же ошибку в приложении Windows Store, все, что я вижу, это
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
(Edit: это в файле с именем App.g.i.cs
)
И тогда я должен внимательно посмотреть на результат, чтобы найти
WinRT information: Cannot resolve TargetProperty (Canvas.MispelledProperty) on specified object.
Теперь в некоторых случаях этого может быть достаточно, но мне действительно трудно поверить, что это все, что вы можете получить. У меня возникла некоторая проблема, связанная с нюансами в том, как Storyboar работает довольно легко отсортирован (завершенные события прикреплены непосредственно к анимации, где не запускается, как в WPF-коллеге), но сейчас я совершенно не знаю об этой ошибке:
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred
вызвано просто диким щелчком, что также приводит к сбою всего приложения.
Теперь мое приложение действительно тривиально и, вероятно, имеет какое-то отношение к тому, как я обрабатываю события PointerPressed
и PointerReleased
, но это действительно расстраивает, чтобы не было с чем-то лучше начать.
Итак, я думаю, что фактический вопрос был бы: действительно ли это должно быть так, или я могу настроить отладчик, чтобы дать мне более полезную информацию? И если нет, то: Какие методы отладки/обходные пути вы используете при разработке приложений Windows Store?
ОБНОВЛЕНИЕ:
Сначала мне показалось, что это произошло только с WinRT, связанным с исключением, что там, где происходит вне CLR и где не правильно завернуто, но все необработанные исключения переведут вас на App.g.i.cs
вместо того места, где они произошли. Например, я намеренно пытался получить доступ к списку из этого диапазона в методе, чтобы увидеть, увидит ли Visual Studio меня там, когда возникло исключение, но вместо этого он снова взял меня на App.g.i.cs
. В локалях я получаю этот Windows.UI.Xaml.UnhandledExceptionEventArgs
, а строка сообщения содержит некоторую информацию, которая почти похожа на трассировку стека, но не имеет номеров строк. Вот пример моей преднамеренной ошибки:
System.ArgumentOutOfRangeException
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at StorePuzzle.PuzzleRenderer.HandleTileReleased(Object sender, PointerRoutedEventArgs e)
Все, что я хочу, это Visual Studio, чтобы сразу взять меня на место, где возникает исключение, вместо того, чтобы отвезти меня в App.g.i.cs
так же, как в "Non Store Apps". Теперь эти директивы препроцессора компилятора делают его похожим на то, что я мог просто отключить его (#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
), но googleing он не показал мне никакого способа сделать это.
Ответы
Ответ 1
У меня очень похожий вопрос о получении следов стека и отвалов, которые я задал здесь: Как получить журналы сбоев и трассировки стека из приложений WinRT, написанных на С#?.
Microsoft делает получение информации об авариях из приложений WinRT очень сложной по сравнению с Android. В отличие от Android нет встроенного журнала, такого как logcat, где вы можете понять, почему ваше приложение разбилось с простой трассировкой стека. Android дает это разработчикам и не просит их написать одну строку кода!
В приложениях WinRT Похоже, что нам всем приходится сворачивать собственные решения этой проблемы. Есть много разных мест, которые могут иметь место исключения, если вы хотите зарегистрировать их все - и какова точка регистрации исключений, если вы не регистрируете их всех - похоже, что это будет очень много работы!
В этой статье дается некоторое объяснение, как поймать исключения XAML, чтобы вы могли их зарегистрировать:
В этой статье объясняется, почему вам необходимо обернуть весь код в ваших обратных вызовах async-события с помощью try/catch:
Эта библиотека выглядит как хороший выбор для ведения журнала, хотя она кажется немного тяжелой, поскольку она полагается на SQLite, если есть более легкий выбор, который нуждается в базе данных, которая может быть предпочтительной.
UPDATE:
Microsoft анонсировала некоторые новые возможности ведения журнала в Windows 8.1, теперь документы находятся здесь:
http://msdn.microsoft.com/en-us/library/windows/apps/windows.foundation.diagnostics.loggingchannel
Ответ 2
Отладка исключений в вашем коде, когда вы знаете конкретный тип исключения, который вы ищете, прост.
Выберите Debug
, затем Exceptions
в меню (или Ctrl+D
Ctrl+E
)
Найдите свое конкретное исключение и проверьте thrown
.
Отладчик остановится прямо в строке кода, где происходит исключение.
У меня обычно есть большинство исключений, чтобы найти проблемы на раннем этапе.
Ошибки в XAML - это разные зверь, хотя иногда их очень трудно найти.
Ответ 3
Об ArgumentOutOfRangeException: Отладчик в Visual Studio имеет специальную опцию для разных видов исключений, вам нужно убедиться, что вы выбрали "Брошенный" для своего исключения (вы можете выбрать все исключения для обычного языка Runtime Exceptions в вашем случае) http://msdn.microsoft.com/en-us/library/d14azbfh.aspx
О WinRT: С WinRT я предполагаю, что это немного другой случай. Я не настоящий эксперт в WinRT, но он смотрит на меня, что Windows фактически работает с XAML по-разному, чем WPF. В Windows больше всего работает async (например, создание элементов управления, разбор XAML и т.д.). Вот почему вы в основном получаете исключения из XAML, где вы не пытаетесь установить свойства, а как Unhandled Exceptions.
Ответ 4
![Locals in VS2012]()
Если вы посмотрите на панели "Местные жители" в Visual Studio 2012, вы увидите значение, называемое $exception, когда вызывается исключение. Если вы развернете его, вы сможете узнать всевозможную информацию о проблеме.