Burak Özmen
Burak Özmen

Reputation: 873

Using await hinders the process of program

I'm coding an app for Windows 8 which needs to get the HTML of a particular site. It was working well when i coded it into the button event which is in the MainPage. However, when I tried to do it in my class 'Band':

        public Band(String Name)
    {
        this.Name = Name;
        GetHtmlDocument();
        GenerateId();
        GetAlbumDocument();
        GenerateLogo();
        GeneratePhoto();
        CreateAlbumList();
    }

    private async void GetHtmlDocument()
    {
        HttpClientHandler handler = new HttpClientHandler();
        HttpClient client = new HttpClient(handler as HttpMessageHandler) { BaseAddress = new Uri(@"http://www.metal-archives.com/bands/" + Name) };
        var r = await client.GetAsync(client.BaseAddress);
        string html = null;
        if (r.IsSuccessStatusCode) html = await r.Content.ReadAsStringAsync();
        HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
        document.LoadHtml(html);
        DocumentBand = document;
    }

It came to

var r = await client.GetAsync(client.BaseAddress);

line and then proceed from the GenerateId() method as it is in the constructor. But in order to process GenerateId() method, GetHtmlDocument() method must be finished. What should i do in this situation?

My main language is Java and I'm very new to the C#, so there may huge coding or naming mistakes.

Upvotes: 0

Views: 337

Answers (2)

chue x
chue x

Reputation: 18803

I would do something like this:

    public Band(String Name)
    {
        this.Name = Name;
    }

    public async Task Init()
    {
        await GetHtmlDocument();
        GenerateId();
        GetAlbumDocument();
        GenerateLogo();
        GeneratePhoto();
        CreateAlbumList();
    }

    // Note Task Return type
    private async Task GetHtmlDocument()
    {
        HttpClientHandler handler = new HttpClientHandler();
        HttpClient client = new HttpClient(handler as HttpMessageHandler) { BaseAddress = new Uri(@"http://www.metal-archives.com/bands/" + Name) };
        var r = await client.GetAsync(client.BaseAddress);
        string html = null;
        if (r.IsSuccessStatusCode) html = await r.Content.ReadAsStringAsync();
        HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
        document.LoadHtml(html);
        DocumentBand = document;
    }

From your code, you would have to call init separately:

 Band band = new Band("name");
 await band.Init();

The reason for having a separate Init() function is because async and await cannot be used inside of the constructor.

Upvotes: 0

lboshuizen
lboshuizen

Reputation: 2786

Although your function GetHtmlDocument has an async signature it't not called regarding that signature.

You call client.GetAsync() in your function. That will give control back to the calling function, in this case the constrcutor of Band without waiting for the result.

Changing the call to

await GetHtmlDocument()

Should bring things in sync.

Upvotes: 2

Related Questions