web-dev-qa-db-ja.com

.Net Core 2.1のHttpClientがハングする

次の.Net Core 2.1コンソールアプリの場合...

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;

namespace TestHttpClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                    

                    string url = "https://jsonplaceholder.typicode.com/posts/1";
                    var response = httpClient.GetAsync(url).Result;
                    string jsonResult = response.Content.ReadAsStringAsync().Result;   
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }
    }
}

GetAsyncを呼び出すと、次のメッセージが表示されて例外がスローされます。

System.Net.Http.HttpRequestException:接続されたパーティが一定時間後に適切に応答しなかったために接続試行が失敗したか、接続されたホストが応答に失敗したために確立された接続が失敗しました---> System.Net.Sockets.SocketException:A接続されたパーティが一定時間後に適切に応答しなかったため、または接続されたホストが応答しなかったために確立された接続が失敗したため、接続試行が失敗した

ただし、.Net Core 2.0に切り替えると正常に動作します...

[〜#〜] note [〜#〜]

私は使用してみました:

HttpClientFactory -> Same result
WebRequest        -> Same result

考え?

UPDATE 1これは、企業ネットワーク上にないときに機能します。これは、プロキシの動作の変更を意味する場合がありますおそらく。ただし、core2.0は関係なく動作するため、違いを見つけようとします。

UPDATE 2バグが導入され、報告されているようです...

https://github.com/dotnet/corefx/issues/30166#issuecomment-3954896

10
Jim

そのため、これに関してバグ/重大な変更が報告されているようです。

ここ: https://github.com/dotnet/corefx/issues/30166https://github.com/dotnet/corefx/issues/30191

私が経験しているのは、2つの別個だが関連する問題だと思います。

しかし、回避策と思われるものを見つけました。

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace TestHttpClient
{
    static class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                using (var httpClient = new HttpClient(new WinHttpHandler() { WindowsProxyUsePolicy = WindowsProxyUsePolicy.UseWinInetProxy }))
                {
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    string url = "https://jsonplaceholder.typicode.com/posts/1";                   

                    var response = await httpClient.GetAsync(url);
                    string jsonResult = await response.Content.ReadAsStringAsync();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                throw;
            }
        }
    }
}

ここで重要なのは、WinHttpHandlerを使用し、WindowsProxyUsePolicyWindowsProxyUsePolicy.UseWinInetProxyに設定することです

WinHttpHandlerは、nugetパッケージを追加することで見つかります System.Net.Http.WinHttpHandler

9
Jim

これは、HttpClientが新しいHttpClientHandlerを使用するCoreFx 2.1の変更でした。これが問題の原因であり、ダウングレードが機能する理由です。

ハンドラーをリセットするには多くの方法があり、詳細については change log を参照してください。古いHttpHandlerを使用するには、パラメーターとしてWinHttpHandlerを使用してHttpClientをインスタンス化し、環境変数DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLERをfalseに設定するか、コードで次を呼び出します。

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
12
Daniel Gimenez

これは有名な「21秒」タイムアウトの問題です...まれな呼び出し(私のサービスはAzureインフラストラクチャから外部サービスを呼び出しています)でAzureに役立つものは以下を追加することです:

httpClient.DefaultRequestHeaders.ConnectionClose = true;
0
Pavel Biryukov