使用await阻碍了程序的进程

时间:2013-01-13 22:41:40

标签: c# asynchronous windows-8

我正在为Windows 8编写一个应用程序,需要获取特定网站的HTML。当我将它编码到MainPage中的按钮事件时,它运行良好。但是,当我在班级'乐队'中尝试这样做时:

        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;
    }

来到了

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

行然后从构造函数中的GenerateId()方法继续。但是为了处理GenerateId()方法,必须完成GetHtmlDocument()方法。在这种情况下我该怎么办?

我的主要语言是Java,我对C#很新,所以可能存在大量的编码或命名错误。

2 个答案:

答案 0 :(得分:2)

虽然你的函数GetHtmlDocument有一个异步签名,但是没有关于该签名调用它。

您在函数中调用client.GetAsync()。这将控制回到调用函数,在这种情况下是Band的构造函数,而不等待结果。

将通话更改为

await GetHtmlDocument()

应该让事情保持同步。

答案 1 :(得分:0)

我会做这样的事情:

    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;
    }

从您的代码中,您必须单独调用init:

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

具有单独的Init()函数的原因是因为asyncawait不能在构造函数内使用。