2

I have created a simple async operation which is being kicked of when the button is clicked. Here is the whole code:

public partial class MainWindow : Window {

    public MainWindow() {
        InitializeComponent();
    }

    private async void Button_Click_1(object sender, RoutedEventArgs e) {

        var htmlString = await DowloadPage("http://example.com");
        txtBlock1.Text = htmlString;
    }

    public async Task<string> DowloadPage(string uri) {

        using (WebClient client = new WebClient()) {

            var htmlString = await client.DownloadStringTaskAsync(uri);
            return htmlString;   
        }
    }

}

Very easy. But when I click the button, I experience unresponsiveness on the UI thread. When I try to move around the window while the page is being downloaded, I am unable to.

Any idea what is going wrong?

Edit:

I tried with HttpClient in .NET 4.5 and it worked out pretty great as expected:

public async Task<string> DowloadPage(string uri) {

    using (HttpClient client = new HttpClient()) {

        var response = await client.GetAsync(uri);
        var htmlString = await response.Content.ReadAsStringAsync();
        return htmlString;   
    }
}


  • BTW there is a new HttpClient Class in .NET 4.5 which is designed for async/await. - dtb
  • @dtb I am aware of that. Thanks but the issue here is different. - tugberk
  • How long is htmlString? It may simply take some time to render the txtBlock1 with it. - dtb
  • @dtb do you think that newing up the WebClient would cause that blocking? - tugberk
  • No, creating a WebClient instance is really lightweight. Have you checked how long htmlString is (see my comment above)? - dtb

1 답변


4

WebClient uses HttpWebRequest, which unfortunately is not very asynchronous, even if you use the "asynchronous" methods. It does a blocking DNS lookup, at least. It may also block during proxy negotiation and/or the initial HTTP connection.

An older release of HttpClient was just using a wrapper around HttpWebRequest. I requested a truly-asynchronous HttpClient, but never heard a response. The last time I checked HttpClient, it was still part of MVC; ASP.NET Web API wasn't around at that time, so they may have fixed HttpClient since then. Or the difference in behavior between WebClient and HttpClient on your machine may just have to do with DNS caches or some such.


  • Inside the download method (not the handler), should it ConfigureAwait(false) since its particular continuation doesn't need to be on the UI thread? Obviously the handler shouldn't do so. :) - James Manning
  • I would. It's best practice to do so, but (in this case) it won't cause any problems (like deadlocks) if he doesn't - it's just not as efficient as it could be. - Stephen Cleary
  • I assume that since the questioner said HttpClient 'worked out great' that it was indeed 'fixed' to your liking? - Simon_Weaver
  • I believe it has not been fixed. I examined it in dotPeek and the same call structure exists (HttpClient -> HttpWebRequest -> ServicePoint -> blocking DNS request). - Stephen Cleary

Linked


Related

Latest