maztt
maztt

Reputation: 12294

async await execution windows phone 8

I am new to async and await style of programming. How can I solve the following problem:

I am calling the below code first. The problem here is that the first line is awaiting which need to populate the categoriesvm.Categorieslist, which it does not, but the second line is called. (which I think is the default behaviour of await)

How can I make sure that the second line is called only when the categoriesvm.Categorieslist is populated in the first line?

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    categoriesvm.GetCategories();                 
    BookCategories.DataContext = from vm in categoriesvm.Categorieslist select vm;
}

In the code above when I execute the first line it goes below where Categorieslist is the list I am accessing above.

public async void GetCategories()
{            
    Categorieslist = new ObservableCollection<Categories>(await PhoneClient.GetDefaultCategories());          
}

The phoneclient is below

public class PhoneClient
{   
    private static readonly HttpClient client;

    public static Uri ServerBaseUri
    {
        get { return new Uri("http://169.254.80.80:30134/api/"); }
    }

    static PhoneClient()
    {        
       client =new HttpClient();
       client.MaxResponseContentBufferSize = 256000;
       client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
    }      

    public async static Task<List<Categories>> GetDefaultCategories()
    {      
        HttpResponseMessage getresponse = await client.GetAsync(ServerBaseUri + "Categoryss");                      
        string json = await getresponse.Content.ReadAsStringAsync();         
        json = json.Replace("<br>", Environment.NewLine);
        var categories = JsonConvert.DeserializeObject<List<Categories>>(json);
        return categories.ToList();
    }
}

Upvotes: 1

Views: 5601

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456417

You should avoid async void. I explain this guideline in an MSDN article.

Once you change your async void method to async Task:

public async Task GetCategoriesAsync()
{            
  Categorieslist = new ObservableCollection<Categories>(await PhoneClient.GetDefaultCategories());          
}

Then you can await it as such:

protected override async void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
  await categoriesvm.GetCategoriesAsync();                 
  BookCategories.DataContext = from vm in categoriesvm.Categorieslist select vm;
}

However, I recommend doing all your VM initialization outside of your UI events - this will make your code easier to test. Take a look at my async constructors blog post for ideas.

Upvotes: 7

Related Questions