Как поймать system.xml.xmlexception

1

Я опубликовал небольшое бесплатное приложение для смартфонов Windows Phone 8 (чтобы познакомиться с С#, поэтому я начинаю программировать). Многие мои пользователи очень довольны функциональностью, но некоторые из них, похоже, продолжают получать случайные сбои (например, в Канаде: http://www.windowsphone.com/en-ca/store/app/picture-of-the -day/fc977a34-c09d-4c70-8a7b-66b6f09ab7f0) Я никогда не испытывал таких сбоев на своих тестовых устройствах и пытался избавиться от них, добавив несколько утверждений try-catch - но безуспешно.

В отчете о сбое говорится следующее:

Frame Image Function Offset        
0 system_xml_ni System.Xml.XmlTextReaderImpl.Throw 0x00000036    
1 system_xml_ni System.Xml.XmlTextReaderImpl.ParseDocumentContent 0x00000438    
2 system_xml_ni System.Xml.XmlTextReaderImpl.Read 0x00000036    
3 system_xml_linq_ni System.Xml.Linq.XDeclaration..ctor 0x00000072    
4 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x0000010a    
5 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x00000042    
6 system_xml_linq_ni System.Xml.Linq.XDocument.Load 0x00000006    
7 phoneapp1_ni PhoneApp1.MainPage+__c__DisplayClassb._doLoadURL_b__6 0x00000040    
8 system_net_ni System.Net.WebClient.OnOpenReadCompleted 0x00000010    
9 system_net_ni System.Net.WebClient.OpenReadOperationCompleted 0x00000034'

Фактический код, который, как я думаю, отвечает:

try 
{
    WebClient client = new WebClient();
    client.OpenReadAsync(new Uri(Url, UriKind.Absolute));
    client.OpenReadCompleted += (sender, e) =>
    {
        if (e.Error != null)
        {
            return;
        }
        else
        {
            System.Xml.Linq.XDocument xmlDoc = XDocument.Load(e.Result);
            IEnumerable<string> strTestURL = from node in xmlDoc.Descendants("url") select node.Value;
            IEnumerable<string> strTestDescription = from node in xmlDoc.Descendants("copyright") select node.Value;
            IEnumerable<string> strTestDate = from node in xmlDoc.Descendants("enddate") select node.Value;
            string strURL = "http://www.bing.com" + strTestURL.First();
            strURL = strURL.Replace("1366x768", "800x480");
            Global.URL1 = strURL;
            Global.URLs[i] = strURL;
            Global.Descriptions[i] = strTestDescription.First();
            Uri Uri = new Uri(Global.URLs[i], UriKind.Absolute);
            Imageallgemein.Source = new BitmapImage(Uri);
            Imageallgemein.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
            Imageallgemein.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
            Description.Text = Global.Descriptions[i];
            string Year = strTestDate.First().Substring(0, 4);
            string Month = strTestDate.First().Substring(4, 2);
            string Day = strTestDate.First().Substring(6, 2);
            Date.Text = Day + "." + Month + "." + Year;
        }
    };
}
catch
{
    MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
}

try-catch, кажется, не имеет никакого эффекта, и я надеюсь, что кто-то сможет решить это для меня.

  • 0
    Покажите нам проблемный код, пожалуйста
  • 0
    будет делать - не думал, что кто-то будет так быстро
Показать ещё 3 комментария
Теги:
visual-studio
windows-phone-8

2 ответа

3
Лучший ответ

Должна быть какая-то проблема с XML, предоставленным e.Result. Подробности об этом могут быть в сообщении XmlException но вы включили только часть трассировки стека.

Вам нужно будет выяснить, в чем проблема в первую очередь, и вам, вероятно, придется добавить некоторые записи о том, что происходит до того, как вы вызываете XDocument.Load если вы не можете воспроизвести проблему в своей собственной системе.

Вы также можете добавить обработчик исключений, но это не устраняет проблему, но делает ваше приложение более надежным и позволяет ему немного улучшить интерфейс пользователя, если произойдет что-то неожиданное. Вы сделали добавление обработчика исключений вокруг вызовов методам WebClient но вы не client.OpenReadCompleted исключения, вызванные обработчиком для client.OpenReadCompleted. client.OpenReadCompleted. Это асинхронный обратный вызов, который будет выполняться в потоке threadpool, и любые неперехваченные исключения, создаваемые этим потоком, прекратят ваше приложение.

Вам нужно обработать исключение с помощью кода следующим образом:

client.OpenReadCompleted += (sender, e) =>
{
    try
    {
        if (e.Error != null)
        {
            return;
        }
        else
            ....
    }
    catch (Exception ex)
    {
        .... log and report the exception to allow the app to continue
    }
 }

И если вы решите добавить журнал в свое приложение, это будет очень полезно для вас, если вы зарегистрируете весь текст, возвращенный ex.ToString(). Это даст вам хорошее текстовое описание проблемы, включая внутренние исключения и полные следы стека.

  • 0
    Я всегда думал, что должно быть что-то не так с предоставленным XML, но есть очень много пользователей, у которых нет никаких проблем, и только некоторые испытывают сбои - это действительно странно. Я попробую ваше решение и обновлю свое приложение - поскольку я не могу воспроизвести эту ошибку на своих устройствах, мне нужно, чтобы затронутые пользователи протестировали ее и посмотрели, работает ли она (например, посмотрите, не падает ли число сбоев). Я думал, что try-catch перехватит все, что происходит внутри, поэтому я не стал добавлять его в OpenReadCompleted. Я думаю, мы увидим, как это будет.
  • 0
    Большое спасибо, и я отмечу это как ответ, как только смогу подтвердить, что это решение моей проблемы.
Показать ещё 3 комментария
2

Обычно является хорошей практикой делать catch(Exception), в вашем случае catch(system.xml.XmlException). Однако поставите try-catch внутри вашего блока else, потому что это асинхронное событие, и если произойдет какое-то исключение внутри этого исключения, он не будет зацепиться:

try 
{
    WebClient client = new WebClient();
    client.OpenReadAsync(new Uri(Url, UriKind.Absolute));
    client.OpenReadCompleted += (sender, e) =>
    {
        if (e.Error != null)
        {
            return;
        }
        else
        {
           try
           {
              System.Xml.Linq.XDocument xmlDoc = XDocument.Load(e.Result);
              IEnumerable<string> strTestURL = from node in xmlDoc.Descendants("url") select node.Value;
              IEnumerable<string> strTestDescription = from node in xmlDoc.Descendants("copyright") select node.Value;
              IEnumerable<string> strTestDate = from node in xmlDoc.Descendants("enddate") select node.Value;
              string strURL = "http://www.bing.com" + strTestURL.First();
              strURL = strURL.Replace("1366x768", "800x480");
              Global.URL1 = strURL;
              Global.URLs[i] = strURL;
              Global.Descriptions[i] = strTestDescription.First();
              Uri Uri = new Uri(Global.URLs[i], UriKind.Absolute);
              Imageallgemein.Source = new BitmapImage(Uri);
              Imageallgemein.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
              Imageallgemein.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(onImageTap);
              Description.Text = Global.Descriptions[i];
              string Year = strTestDate.First().Substring(0, 4);
              string Month = strTestDate.First().Substring(4, 2);
              string Day = strTestDate.First().Substring(6, 2);
              Date.Text = Day + "." + Month + "." + Year;
           }
           catch (XmlException)
           {
                MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
           }
        }
    };
}
catch (Exception)
{
    MessageBox.Show(AppResources.Abort, AppResources.msgBoxUrlLoadError, MessageBoxButton.OK);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню