C# HttpClient的单个实例与具有ClientCredentias的多个实例?

C# HttpClient的单个实例与具有ClientCredentias的多个实例?,c#,httpclient,x509certificate,credentials,socketexception,C#,Httpclient,X509certificate,Credentials,Socketexception,我正在使用HttpClient向Soap Api发出请求。 我看到建议对每个请求使用一个HttpClient实例,而不是一次,以避免SocketException 在我的桌面应用程序中,我需要发出多个请求,每个请求都有不同的凭据。我按照示例代码进行操作: WebRequestHandler requestHandler = new WebRequestHandler(); requestHandler.ClientCertificates.Add(certificate); using(var

我正在使用HttpClient向Soap Api发出请求。 我看到建议对每个请求使用一个HttpClient实例,而不是一次,以避免SocketException

在我的桌面应用程序中,我需要发出多个请求,每个请求都有不同的凭据。我按照示例代码进行操作:

WebRequestHandler requestHandler = new WebRequestHandler();
requestHandler.ClientCertificates.Add(certificate);

using(var client = new HttpClient(requestHandler))
{
    try
    {
        HttpResponseMessage response = await client.PostAsync("https://nfe-homologacao.svrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.asmx", httpContent);
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        return responseBody;
    }
    catch (HttpRequestException e)
    {
        return e.Message;
    }
}
但是,我希望避免为每个请求创建一个HttpClient实例。我看到正确的方法是像这样使用静态实例:

static readonly HttpClient client = new HttpClient();
但对于静态实例,我无法使用WebRequestHandler设置凭据。请注意,每个请求中的凭据都会更改


执行所有请求、避免SocketException和使用不同凭据的更好方法是什么?

通常应为创建的每个请求设置每个请求凭据:

var request = new HttpRequestMessage();
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
await client.SendAsync(request);
您也可以在自己的web请求处理程序中执行此操作:

class SetCredentialsWebRequestHandler : WebRequestHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
        return base.SendAsync(request, cancellationToken);
    }
}

client = new HttpClient(new SetCredentialsWebRequestHandler());
await client.PostAsync(url);
class SetCredentialsWebRequestHandler:WebRequestHandler
{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
request.Headers.Authorization=new System.Net.Http.Headers.AuthenticationHeaderValue(“载体”);
返回base.sendaync(请求、取消令牌);
}
}
client=new-HttpClient(new-SetCredentialsWebRequestHandler());
等待客户端。PostAsync(url);
更新

从评论中,我了解到问题需要使用证书身份验证。因此,在这种情况下,多个实例(每个证书一个)将是更好的选择

对于不同的客户端证书,重复使用相同的连接是没有意义的

查看此名为
HttpClient


HttpClient
可根据证书命名。

通常,应为创建的每个请求设置每个请求凭据:

var request = new HttpRequestMessage();
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
await client.SendAsync(request);
您也可以在自己的web请求处理程序中执行此操作:

class SetCredentialsWebRequestHandler : WebRequestHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
        return base.SendAsync(request, cancellationToken);
    }
}

client = new HttpClient(new SetCredentialsWebRequestHandler());
await client.PostAsync(url);
class SetCredentialsWebRequestHandler:WebRequestHandler
{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
request.Headers.Authorization=new System.Net.Http.Headers.AuthenticationHeaderValue(“载体”);
返回base.sendaync(请求、取消令牌);
}
}
client=new-HttpClient(new-SetCredentialsWebRequestHandler());
等待客户端。PostAsync(url);
更新

从评论中,我了解到问题需要使用证书身份验证。因此,在这种情况下,多个实例(每个证书一个)将是更好的选择

对于不同的客户端证书,重复使用相同的连接是没有意义的

查看此名为
HttpClient


HttpClient
可以根据证书命名。

谢谢回复!在我的例子中,我使用X509Certificate2代替承载令牌。这个例子也可以吗?不可以。对不起,我认为客户端证书是通用的,您使用的是请求级授权。如果使用证书,则每个证书需要
HttpClient
。证书身份验证发生在SSH/TLS握手期间,即建立连接期间。重用
HttpClient
的关键是重用底层连接,然后我可以创建一个HttpClient列表,并重用具有相同证书的客户端。这是一个好方法吗?但是如果你的应用程序中没有依赖注入的东西,那么是的,列表/字典也可以。只需要确保你最终处理掉它们。是的。列出/字典/你自己的经理类。只要你能在最后不再需要的时候处理它们。如果它们的生命周期与你的应用程序相同,也可以。只是TCP连接将保持半开状态一段时间,然后才能关闭。谢谢回复!在我的例子中,我使用X509Certificate2代替承载令牌。这个例子也可以吗?不可以。对不起,我认为客户端证书是通用的,您使用的是请求级授权。如果使用证书,则每个证书需要
HttpClient
。证书身份验证发生在SSH/TLS握手期间,即建立连接期间。重用
HttpClient
的关键是重用底层连接,然后我可以创建一个HttpClient列表,并重用具有相同证书的客户端。这是一个好方法吗?但是如果你的应用程序中没有依赖注入的东西,那么是的,列表/字典也可以。只需要确保你最终处理掉它们。是的。列出/字典/你自己的经理类。只要你能在最后不再需要的时候处理它们。如果它们的生命周期与你的应用程序相同,也可以。只是TCP连接将保持半开放一段时间,然后才能关闭。