2017-03-17 32 views
4

我正在创建一个应用程序,它以JSON格式从Web服务器请求少量数据,使用Json.net反序列化数据并返回自定义对象的列表。我正在使用Android手机调试应用程序。异步方法中的应用程序崩溃

然后使用创建的列表创建列表视图。 ui代码似乎可以与插入到列表中的预制对象而不是异步方法一起使用。异步方法使应用程序崩溃。

public partial class Membership : ContentPage 
{ 
    int increment = 1; 

    public Membership() 
    { 
     //begin task 
     var task = GetMembers(increment); 

     //irrelevant stuff happening 

     //wait for task to complete to continue execution 
     List<Person> people = task.Result; 


     // Create the ListView. 
     ListView listView = new ListView 
     { 

      // Source of data items. 
      ItemsSource = people, 

      // Define template for displaying each item. 
      // (Argument of DataTemplate constructor is called for 
      //  each item; it must return a Cell derivative.) 
      ItemTemplate = new DataTemplate(() => 
      { 
       // Create views with bindings for displaying each property. 
       Label nameLabel = new Label(); 
       Label statusLabel = new Label(); 


       nameLabel.SetBinding(Label.TextProperty, "name"); 
       statusLabel.SetBinding(Label.TextProperty, "status"); 

       // Return an assembled ViewCell. 
       return new ViewCell 
       { 
        View = new StackLayout 
        { 
         Padding = new Thickness(0, 5), 
         Orientation = StackOrientation.Horizontal, 
         Children = 
          { 
           //boxView, 
           new StackLayout 
           { 
            VerticalOptions = LayoutOptions.Center, 
            Spacing = 0, 
            Children = 
            { 
             nameLabel, 
             statusLabel 
            } 
            } 
          } 
        } 
       }; 
      }) 
     }; 

     // Build the page. 
     this.Content = new StackLayout 
     { 
      Children = 
      { 
       header, 
       listView 
      } 
     }; 


    } 

,问题中的异步任务:

async Task<List<Person>> GetMembers(int increment) 
{ 
     string jsonString; 

     using (var client = new HttpClient()) 
     { 
      //gets the members from the server in json format 
      //increment defines which set of members (1-50, 51-100, etc) 
      var responseString = await client.GetStringAsync("GENERIC URL" + "increment=" + increment.ToString()); 
      jsonString = responseString; 
     } 

     List<Person> memberList = JsonConvert.DeserializeObject<List<Person>>(jsonString); 

     return memberList; 
} 

现在,我已经通过绕过异步任务和创建几个预定义的人们的名单测试此代码,和它的工作就好了。

我明白使用task.Result;方法将阻止应用程序,直到异步任务完成,但是,当单元测试没有速度问题时,所以我有点困惑。任何帮助,将不胜感激。

+2

你有任何ErrorMessage?什么意思是应用程序崩溃?确保Task.Result可以导致死锁:http://stackoverflow.com/questions/17248680/await-works-but-calling-task-result-hangs-deadlocks – Sebi

+0

没有错误信息,它只是冻结。我相信你对僵局可能是正确的。我将不得不研究替代方法来完成这项任务。谢谢。 – BHigzz

+1

是的,这是一个死锁,因为两个线程想要访问相同的上下文。您只需等待该调用并使Membership-Method异步即可。 – Sebi

回答

3

因为你说:

“没有错误信息,它只是冻结。”

在评论中,我相信你在这里有一个死锁的情况。与.Result.Wait()问题在此SO-票被很好地描述:

await works but calling task.Result hangs/deadlocks

你继续试图访问其通过.Result阻止的语境。 你可以重建你的方法是这样的:

public async Task InitializeMembership() 
{ 
    //begin task 
    var task = GetMembers(increment); 

    //irrelevant stuff happening 

    //wait for task to complete to continue execution 
    List<Person> people = await task; 

    //Do further stuff  
} 

正如你可以看到我会用一个方法,而不是构造函数,因为我觉得一个异步的构造是不是最好的做法。我希望这可以解决你的问题。

+0

你是100%正确的Sebi,我感谢你的帮助。我遇到的主要问题是无法将异步级联到顶级方法Membership,因为它实质上是我的主要功能,并且不能是异步。将UI代码放入异步InitializeMembership()函数解决了这个问题。 – BHigzz

+0

@BHigzz您的欢迎。不要忘记标记答案解决请;;)。 – Sebi

相关问题