【问题标题】:Handling exceptions in xamarin处理 xamarin 中的异常
【发布时间】:2018-02-06 11:01:45
【问题描述】:

我在尝试以最佳方式处理某些错误时遇到了一些困难。例如,我的一个案例是 NullReferenceException。

为了更清楚,让我用几句话来解释一下。当我调用服务器接收一些信息时,在某些情况下服务器可能会出现一些问题,它当然会返回null

我所做的是显示一个警报,让用户知道他可以稍后再试。在此之后,我尝试将他发送到上一页。毕竟,我的应用程序仍然崩溃。

我想要做的是简单地显示警报,然后让用户留在同一页面而不会使应用程序崩溃。

这是我的一些代码:

tasks.cs

 public async Task<List<Idea>> GetIdeaAsync(string accesToken)
  {
      List<Idea> ideas = null;
      try
      {
         var client = new HttpClient();
         client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesToken);

         var json = await client.GetStringAsync("http://www.getdata.de/api/ideas/");
         var ideas = JsonConvert.DeserializeObject<List<Idea>>(json);
      }
      catch (Exception ex)
      {
        await Application.Current.MainPage.DisplayAlert("Server Error", "There has been an server error. Please try later.", "OK");
              if (ideas == null)
              {
                  await Application.Current.MainPage.Navigation.PopAsync(); //actually I would like to stay in the same page
              }
      }
      return ideas;
  }

view.xaml.cs

private async void Button_Clicked(object sender, EventArgs e)
 {
    Tasks ts = new Tasks();
    var ideas = await ts.GetIdeasAsync();
    if (ideas == null)
    {
        Debug.WriteLine("hello");
        //do nothing since the display alert is already shown
    }
    else
    {
      //code here
    }

如果有人能指导我采用“最佳实践”方法,我将不胜感激。谢谢:)

【问题讨论】:

  • 您正在捕获致命异常。这是异常处理的致命罪过。您应该适当地阅读正确的异常处理。以下是我经常链接的两篇文章,它们应该可以帮助您快速了解:blogs.msdn.com/b/ericlippert/archive/2008/09/10/…codeproject.com/Articles/9538/…
  • 好的@Christopher 我会尝试阅读这些文章。我想我需要它们:)
  • 您是否尝试在 Device.BeginInvokeOnMainThread 中运行 DisplayAlertPopAsync?从辅助线程访问 UI 线程可能会导致致命异常。
  • @DiegoRafaelSouza 这个异常不是我做的,因为它是一个致命的异常,我无法阻止它。在这种情况下,存在服务器问题。我的问题是异常处理。无论如何我已经解决了,所以谢谢你的帮助。
  • 太棒了,你解决了!无论如何,我不确定你不能处理或不能做任何事情来阻止它。这种异常会强制停止应用程序,但它是由 SO(在您的情况下为 Android)管理的,并且通常由不正确的资源访问引起。这就是我的意思(对不起我的英语不好)

标签: c# exception xamarin exception-handling xamarin.forms


【解决方案1】:

您在 try 块中声明 ideas,然后尝试在超出范围的 catch 块中访问它。 (Visual Studio 应该给出一个 Intellisense 错误)

此外,无论何时操作 UI,都应始终在主线程上进行。所以将你的DisplayAlert() 代码移动到

Device.BeginInvokeOnMainThread(async () => 
{
    // await DisplayAlert(); move it into here
});

此外,任何PopAsyncPushAsync 调用也应该在主UI 线程上完成。但是在异步调用 API 之后调用 PopAsync 并不是一个好主意,因为在调用返回时用户可能已经按下了返回按钮。

对于 NullReferenceException,在将其传递给 DeserializeObject() 函数之前,请检查 json 是否为 null。

【讨论】:

  • (await () =&gt; ?你的意思是(async () =&gt;?我不确定这如何回答这个问题
  • @sme 这不是我真正的代码只是一个复制品。我现在编辑了它,我认为这一切都很好。但无论如何我不明白这如何回答我的问题:/
  • @John 好的,我明白了。在这种情况下,如果您希望用户停留在同一页面上,只需删除 PopAsync() 调用
  • 我想通了。问题是异常处理。该应用程序崩溃,因为它是一个致命的例外。这就是我的问题
【解决方案2】:

这个问题其实很明显,因为我在捕获异常之后会继续编写代码。所以我所做的是:

public async Task<List<Idea>> GetIdeaAsync(string accesToken)
{
  List<Idea> ideas = null;
  try
  {
     var client = new HttpClient();
     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesToken);

     var json = await client.GetStringAsync("http://www.getdata.de/api/ideas/");
     var ideas = JsonConvert.DeserializeObject<List<Idea>>(json);
  }
  catch (Exception ex)
  {
    await Application.Current.MainPage.DisplayAlert("Server Error", "There has been an server error. Please try later.", "OK");
          if (ideas == null)
          {
              //actually I would like to stay in the same page
              return null; //-- added this line 
          }
  }
   return ideas;
}

也许这不是最好的主意,但它对我有用。任何其他方法将不胜感激。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    相关资源
    最近更新 更多