2

ボタンがクリックされたときにキックされる単純な非同期操作を作成しました。これが全体のコードです。

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

}

非常に簡単。しかし、ボタンをクリックすると、UIスレッドが反応しなくなります。ページのダウンロード中にウィンドウを移動しようとすると、できません。

何がうまくいかないのですか?

編集する

私は.NET 4.5でHttpClientを試してみましたが、予想通りかなりうまくいきました。

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


  • ところで新しいがありますHttpClientクラス.NET 4.5では、次の目的のために設計されています。async/await。 - dtb
  • @ dtb私はそれを知っています。ありがとう、でもここの問題は違う。 - tugberk
  • どれくらいのhtmlString?レンダリングに時間がかかることがあります。txtBlock1それと。 - dtb
  • @dtbあなたは新しいことを考えていますかWebClientそのブロッキングを引き起こすだろうか? - tugberk
  • いいえ、作成中WebClientインスタンスは本当に軽量です。どのくらいチェックしましたかhtmlString(上記の私のコメントを参照)ですか? - dtb

1 답변


4

WebClient用途HttpWebRequest残念ながら非同期ではありませんたとえあなたが "非同期"メソッドを使ったとしても。少なくとも、ブロッキングDNSルックアップを行います。プロキシネゴシエーションおよび/または最初のHTTP接続中にもブロックされる可能性があります。

の古いリリースHttpClientただラッパーを使っていたHttpWebRequest。私本当に非同期を要求しましたHttpClientしかし、応答を聞いたことがない。私が最後にチェックした時HttpClientそれはまだMVCの一部でした。当時ASP.NET Web APIは登場していなかったため、修正された可能性がありますHttpClientそれ以来。または間の動作の違いWebClientそしてHttpClientあなたのマシンではDNSキャッシュなどと関係があるかもしれません。


  • ダウンロードメソッドの内部(ハンドラではない)では、その特定の継続がUIスレッド上にある必要はないので、ConfigureAwait(false)にする必要がありますか。明らかにハンドラはそうしてはいけません。 :) - James Manning
  • 私は...するだろう。これを実行するのがベストプラクティスですが、(この場合は)デッドロックなどの問題が発生することはありません。可能な限り効率的ではありません。あります。 - Stephen Cleary
  • 質問者がHttpClient'がうまく機能したと述べたので、本当に修正されました。あなたの好みに? - Simon_Weaver
  • 修正されていないと思います。 dotPeekで調べたところ、同じ呼び出し構造が存在します(HttpClient - >HttpWebRequest - >ServicePoint - > DNS要求をブロックします。 - Stephen Cleary

リンクされた質問


関連する質問

最近の質問