5

次のコードがあります

static void Main(string[] args)
{
        string url = "http://www.google.com";
        Console.WriteLine(GetUrl(url).Result); // throws TaskCanceledException
        Console.WriteLine(GetUrl2(url).Result);
    }

    public static Task<string> GetUrl(string url)
    {
        using (var client = new HttpClient())
        {
            return client.GetStringAsync(url);
        }
    }

    public static Task<string> GetUrl2(string url)
    {
        using (var client = new WebClient())
        {
            return client.DownloadStringTaskAsync(url);
        }
    }

問題は、GetUrl メソッド (HttpClient の GetStringAsync を使用) が TaskCacelledException をスローすることですが、GetUrl2 メソッド (WebClient の DownloadStringTaskAsync を使用) は正しく実行されます。これは が原因using statementですか? 私は何が欠けていますか?

編集。この例では、これがコンソール アプリケーションであるため、タスクで Result を呼び出しています。たとえば、イベント ハンドラーで結果を待機するのが最善であることがわかっています。

4

1 に答える 1

9

これは using ステートメントが原因ですか?

はい。どちらのコード例でも、操作が完了する前に基になるクライアントを破棄しています。両方のコード例を次のように変更する必要があります。

public static async Task<string> GetUrlAsync(string url)
{
    using (var client = new HttpClient())
    {
        return await client.GetStringAsync(url);
    }
}

public static async Task<string> GetUrl2Async(string url)
{
    using (var client = new WebClient())
    {
        return await client.DownloadStringTaskAsync(url);
    }
}

基になるクライアントが破棄されたときの非同期ダウンロードの動作は文書化されていません。コードでクライアントの使用が完了するまで、クライアントを破棄しないことをお勧めします。

于 2014-12-19T18:25:32.763 に答える