Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HttpClient与HttpWebRequest相比,具有更好的性能、安全性和更少的连接_C#_Asp.net Web Api_Httpwebrequest_Httpclient - Fatal编程技术网

C# HttpClient与HttpWebRequest相比,具有更好的性能、安全性和更少的连接

C# HttpClient与HttpWebRequest相比,具有更好的性能、安全性和更少的连接,c#,asp.net-web-api,httpwebrequest,httpclient,C#,Asp.net Web Api,Httpwebrequest,Httpclient,我发现一个HttpClient可以被多个请求共享。如果是共享的,并且请求指向同一目标,则多个请求可以重用连接。WebRequest需要为每个请求重新创建连接 我还查阅了一些关于示例中使用HttpClient的其他方法的文档 以下文章总结了高速NTLM身份验证连接共享: 我尝试过的可能实现如下所示 (A) (B) (C) 如果有人能帮助我了解我应该采取哪种方法来实现最高性能,我将不胜感激,最小化连接并确保安全性不受影响。如果将它们中的任何一个与async一起使用,从性能角度来看,这应该是好的,因

我发现一个HttpClient可以被多个请求共享。如果是共享的,并且请求指向同一目标,则多个请求可以重用连接。WebRequest需要为每个请求重新创建连接

我还查阅了一些关于示例中使用HttpClient的其他方法的文档

以下文章总结了高速NTLM身份验证连接共享:

我尝试过的可能实现如下所示

(A)

(B)

(C)


如果有人能帮助我了解我应该采取哪种方法来实现最高性能,我将不胜感激,最小化连接并确保安全性不受影响。

如果将它们中的任何一个与async一起使用,从性能角度来看,这应该是好的,因为它不会阻塞等待响应的资源,并且您将获得良好的吞吐量

HttpClient优于HttpWebRequest,因为异步方法是现成的,您不必担心编写begin/end方法

基本上,当您使用async调用(使用任何一个类)时,它不会阻塞等待响应的资源,任何其他请求都会利用这些资源进行进一步的调用

要记住的另一件事是,您不应该在“using”块中使用HttpClient来允许对其他web请求重复使用相同的资源

有关更多信息,请参阅下面的线程

  • 您的实现“a”中存在问题。从
    GetWebRequestHandler()
    返回的实例的生存期很短(可能只是为了示例?)。如果是故意这样做的,它将否定对
    HttpClient
    构造函数的第二个参数传递
    false
    false
    的值告诉HttpClient不要处理底层的
    HttpMessageHandler
    (这有助于扩展,因为它不会关闭请求的端口)。当然,这是假设
    HttpMessageHandler
    的生命周期足够长,您可以利用不打开/关闭端口的好处(这对服务器的可伸缩性有很大影响)。因此,我有一个选项“D”的建议

  • 还有一个选项“D”,您没有在上面列出-使
    Httpclient
    实例
    static
    在所有api调用中重复使用。从内存分配和GC的角度来看,这比在客户端打开端口更有效。您没有为
    HttpClient
    实例(及其所有底层对象)分配内存和创建内存的开销,因此也避免了通过GC对它们进行清理


  • 请参考我提供的关于类似问题的答案-

    这是我的ApicClient,它只创建了一次HttpClient。将此对象作为单例注册到依赖项注入库中。重复使用是安全的,因为它是无状态的。不要为每个请求重新创建HTTPClient。尽可能重用Httpclient

    using System;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    //You need to install package Newtonsoft.Json > https://www.nuget.org/packages/Newtonsoft.Json/
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    
    
    public class MyApiClient : IDisposable
    {
        private readonly TimeSpan _timeout;
        private HttpClient _httpClient;
        private HttpClientHandler _httpClientHandler;
        private readonly string _baseUrl;
        private const string ClientUserAgent = "my-api-client-v1";
        private const string MediaTypeJson = "application/json";
    
        public MyApiClient(string baseUrl, TimeSpan? timeout = null)
        {
            _baseUrl = NormalizeBaseUrl(baseUrl);
            _timeout = timeout ?? TimeSpan.FromSeconds(90);   
        }
    
        public async Task<string> PostAsync(string url, object input)
        {
            EnsureHttpClientCreated();
    
            using (var requestContent = new StringContent(ConvertToJsonString(input), Encoding.UTF8, MediaTypeJson))
            {
                using (var response = await _httpClient.PostAsync(url, requestContent))
                {
                    response.EnsureSuccessStatusCode();
                    return await response.Content.ReadAsStringAsync();
                }
            }
        }
    
        public async Task<TResult> PostAsync<TResult>(string url, object input) where TResult : class, new()
        {
            var strResponse = await PostAsync(url, input);
    
            return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        public async Task<TResult> GetAsync<TResult>(string url) where TResult : class, new()
        {
            var strResponse = await GetAsync(url);
    
            return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        public async Task<string> GetAsync(string url)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.GetAsync(url))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public async Task<string> PutAsync(string url, object input)
        {
            return await PutAsync(url, new StringContent(JsonConvert.SerializeObject(input), Encoding.UTF8, MediaTypeJson));
        }
    
        public async Task<string> PutAsync(string url, HttpContent content)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.PutAsync(url, content))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public async Task<string> DeleteAsync(string url)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.DeleteAsync(url))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public void Dispose()
        {
            _httpClientHandler?.Dispose();
            _httpClient?.Dispose();
        }
    
        private void CreateHttpClient()
        {
            _httpClientHandler = new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
            };
    
            _httpClient = new HttpClient(_httpClientHandler, false)
            {
                Timeout = _timeout
            };
    
            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(ClientUserAgent);
    
            if (!string.IsNullOrWhiteSpace(_baseUrl))
            {
                _httpClient.BaseAddress = new Uri(_baseUrl);
            }
    
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeJson));
        }
    
        private void EnsureHttpClientCreated()
        {
            if (_httpClient == null)
            {
                CreateHttpClient();
            }
        }
    
        private static string ConvertToJsonString(object obj)
        {
            if (obj == null)
            {
                return string.Empty;
            }
    
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        private static string NormalizeBaseUrl(string url)
        {
            return url.EndsWith("/") ? url : url + "/";
        }
    }
    
    使用系统;
    Net系统;
    使用System.Net.Http;
    使用System.Net.Http.Header;
    使用系统文本;
    使用System.Threading.Tasks;
    //您需要安装软件包Newtonsoft.Json>https://www.nuget.org/packages/Newtonsoft.Json/
    使用Newtonsoft.Json;
    使用Newtonsoft.Json.Serialization;
    公共类MyApicClient:IDisposable
    {
    专用只读时间间隔\u超时;
    私有httpclientu HttpClient;
    私人HttpClientHandler_HttpClientHandler;
    私有只读字符串\u baseUrl;
    private const string ClientUserAgent=“my-api-client-v1”;
    私有常量字符串MediaTypeJson=“application/json”;
    公共MyApicClient(字符串baseUrl,TimeSpan?timeout=null)
    {
    _baseUrl=NormalizeBaseUrl(baseUrl);
    _超时=超时??从秒开始的时间跨度(90);
    }
    公共异步任务PostAsync(字符串url,对象输入)
    {
    确保已创建TTPClientCreated();
    使用(var requestContent=newstringcontent(ConvertToJsonString(输入),Encoding.UTF8,MediaTypeJson))
    {
    使用(var response=wait_httpClient.PostAsync(url,requestContent))
    {
    response.EnsureSuccessStatusCode();
    return wait response.Content.ReadAsStringAsync();
    }
    }
    }
    公共异步任务PostAsync(字符串url,对象输入),其中TResult:class,new()
    {
    var strResponse=等待后同步(url,输入);
    返回JsonConvert.DeserializeObject(strResponse,新JsonSerializerSettings
    {
    ContractResolver=新的CamelCasePropertyNamesContractResolver()
    });
    }
    公共异步任务GetAsync(字符串url),其中TResult:class,new()
    {
    var strResponse=await GetAsync(url);
    返回JsonConvert.DeserializeObject(strResponse,新JsonSerializerSettings
    {
    ContractResolver=新的CamelCasePropertyNamesContractResolver()
    });
    }
    公共异步任务GetAsync(字符串url)
    {
    确保已创建TTPClientCreated();
    使用(var response=await_httpClient.GetAsync(url))
    {
    response.EnsureSuccessStatusCode();
    return wait response.Content.ReadAsStringAsync();
    }
    }
    公共异步任务PutAsync(字符串url,对象输入)
    {
    return wait-PutAsync(url,新的StringContent(JsonConvert.SerializeObject(输入),Encoding.UTF8,MediaTypeJson));
    }
    公共异步任务PutAsync(字符串url,HttpContent)
    {
    确保已创建TTPClientCreated();
    使用(var response=wait_httpClient.PutAsync(url,内容))
    {
    response.EnsureSuccessStatusCode();
    return wait response.Content.ReadAsStringAsync();
    }
    }
    公共异步任务DeleteAsync(字符串url)
    {
    确保客户
    
    using (HttpClient client = new HttpClient)
    {
    }
    
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("some uri string")
    
    using System;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    //You need to install package Newtonsoft.Json > https://www.nuget.org/packages/Newtonsoft.Json/
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    
    
    public class MyApiClient : IDisposable
    {
        private readonly TimeSpan _timeout;
        private HttpClient _httpClient;
        private HttpClientHandler _httpClientHandler;
        private readonly string _baseUrl;
        private const string ClientUserAgent = "my-api-client-v1";
        private const string MediaTypeJson = "application/json";
    
        public MyApiClient(string baseUrl, TimeSpan? timeout = null)
        {
            _baseUrl = NormalizeBaseUrl(baseUrl);
            _timeout = timeout ?? TimeSpan.FromSeconds(90);   
        }
    
        public async Task<string> PostAsync(string url, object input)
        {
            EnsureHttpClientCreated();
    
            using (var requestContent = new StringContent(ConvertToJsonString(input), Encoding.UTF8, MediaTypeJson))
            {
                using (var response = await _httpClient.PostAsync(url, requestContent))
                {
                    response.EnsureSuccessStatusCode();
                    return await response.Content.ReadAsStringAsync();
                }
            }
        }
    
        public async Task<TResult> PostAsync<TResult>(string url, object input) where TResult : class, new()
        {
            var strResponse = await PostAsync(url, input);
    
            return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        public async Task<TResult> GetAsync<TResult>(string url) where TResult : class, new()
        {
            var strResponse = await GetAsync(url);
    
            return JsonConvert.DeserializeObject<TResult>(strResponse, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        public async Task<string> GetAsync(string url)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.GetAsync(url))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public async Task<string> PutAsync(string url, object input)
        {
            return await PutAsync(url, new StringContent(JsonConvert.SerializeObject(input), Encoding.UTF8, MediaTypeJson));
        }
    
        public async Task<string> PutAsync(string url, HttpContent content)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.PutAsync(url, content))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public async Task<string> DeleteAsync(string url)
        {
            EnsureHttpClientCreated();
    
            using (var response = await _httpClient.DeleteAsync(url))
            {
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
        }
    
        public void Dispose()
        {
            _httpClientHandler?.Dispose();
            _httpClient?.Dispose();
        }
    
        private void CreateHttpClient()
        {
            _httpClientHandler = new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
            };
    
            _httpClient = new HttpClient(_httpClientHandler, false)
            {
                Timeout = _timeout
            };
    
            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(ClientUserAgent);
    
            if (!string.IsNullOrWhiteSpace(_baseUrl))
            {
                _httpClient.BaseAddress = new Uri(_baseUrl);
            }
    
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeJson));
        }
    
        private void EnsureHttpClientCreated()
        {
            if (_httpClient == null)
            {
                CreateHttpClient();
            }
        }
    
        private static string ConvertToJsonString(object obj)
        {
            if (obj == null)
            {
                return string.Empty;
            }
    
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }
    
        private static string NormalizeBaseUrl(string url)
        {
            return url.EndsWith("/") ? url : url + "/";
        }
    }
    
    using ( var client = new MyApiClient("http://localhost:8080"))
    {
        var response = client.GetAsync("api/users/findByUsername?username=alper").Result;
        var userResponse = client.GetAsync<MyUser>("api/users/findByUsername?username=alper").Result;
    }