C# 使用HttpClient和HttpRequestMessage的并发问题
我的代码如下所示:C# 使用HttpClient和HttpRequestMessage的并发问题,c#,mono,dotnet-httpclient,.net-4.6.2,C#,Mono,Dotnet Httpclient,.net 4.6.2,我的代码如下所示: private readonly HttpClient _httpClient; public SomeConstructor(HttpClient httpClient){ _httpClient = httpClient; } public void SomeMethod(string reqUrl, string payload){ var result = GetResponseStringAsync(reqUrl, payload).GetA
private readonly HttpClient _httpClient;
public SomeConstructor(HttpClient httpClient){
_httpClient = httpClient;
}
public void SomeMethod(string reqUrl, string payload){
var result = GetResponseStringAsync(reqUrl, payload).GetAwaiter().GetResult();
// do something with result
}
private async Task<string> GetResponseStringAsync(string reqUrl, string payload){
using (var req = new HttpRequestMessage("POST", reqUrl)){
using (var content = new StringContent(payload)){
// Attach content headers here (specific for each request)
req.Content = content;
// Attach request headers here (specific for each request)
// using req.Headers.TryAddWithoutValidation()
using (var response = await _httpClient.SendAsync(req))
{
return await response.Content.ReadAsStringAsync();
}
}
}
}
private readonly HttpClient\u HttpClient;
公共构造函数(HttpClient HttpClient){
_httpClient=httpClient;
}
公共方法(字符串请求URL、字符串有效负载){
var result=GetResponseStringAsync(请求URL,有效负载).GetAwaiter().GetResult();
//做一些有结果的事情
}
专用异步任务GetResponseStringAsync(字符串请求URL,字符串负载){
使用(var req=newhttprequestmessage(“POST”,reqUrl)){
使用(var内容=新的StringContent(有效负载)){
//在此处附加内容标题(针对每个请求)
要求内容=内容;
//在此处附加请求标题(针对每个请求)
//使用req.Headers.TryAddWithoutValidation()
使用(var response=wait_httpClient.SendAsync(req))
{
return wait response.Content.ReadAsStringAsync();
}
}
}
}
我需要发送每个请求都有不同签名头的API请求,否则我将返回401(未经授权)。也就是说,当我发送一个请求时,我总是得到200,这表明授权头被正确发送。但是,如果我一次发送多个请求(比如并发级别设置为10),则只有一个请求返回了200个请求,而其他9个请求返回了401个请求。但是,如果我单独点击这9个链接,我会像预期的那样,得到每一个链接的200分
在我看来,在某种程度上,存在一个并发性问题,导致正确的头没有附加到相应的请求,即使我为每个请求创建一个新的HttpRequestMessage。HttpClient和HttpRequestMessage都被认为是线程安全的,但是有人能解释一下为什么我在一次发送多个请求时仍然得到奇怪的结果吗
添加:
Container.Register(x=>newsomeconstructor(newhttpclient())代码>因此我确信我没有意外地修改
其他地方的客户
您能否举例说明如何为每个请求添加特定的请求头?i、 e.可能您正在将头添加到共享的
HttpClient
而不是HttpRequestMessage
?当您req.Content=Content
时,您的内容已被删除disposed@vasily.sib糟糕的复制粘贴,我更新了代码。但是没有,它直到API调用完成后才被释放。@caioproitet当然,也只是更新了代码,但我只是使用了req.Headers.TryAddWithoutValidation()
。我需要传递的授权头不完全符合标准格式,因此使用了无验证方法。如果您正在注入,可能会检查类的提升周期,我通常会将其作为单例。不确定您是否在使用.NETCore(因此这可能没有帮助),但如果是这样,它值得一看。实际上,您可以在startup.cs中添加头,然后每次调用客户机实例时都会使用它。另外,值得注意的是,httpclient的某些行为可能是奇怪的,因此,如果您在方法中更改了它的一些配置,它实际上可能会重置头等。您能否举例说明如何为每个请求添加特定的请求头?i、 e.可能您正在将头添加到共享的HttpClient
而不是HttpRequestMessage
?当您req.Content=Content
时,您的内容已被删除disposed@vasily.sib糟糕的复制粘贴,我更新了代码。但是没有,它直到API调用完成后才被释放。@caioproitet当然,也只是更新了代码,但我只是使用了req.Headers.TryAddWithoutValidation()
。我需要传递的授权头不完全符合标准格式,因此使用了无验证方法。如果您正在注入,可能会检查类的提升周期,我通常会将其作为单例。不确定您是否在使用.NETCore(因此这可能没有帮助),但如果是这样,它值得一看。实际上,您可以在startup.cs中添加头,然后每次调用客户机实例时都会使用它。另外,值得注意的是,httpclient的某些行为可能很奇怪,因此,如果您在方法中更改了它的一些配置,它实际上可以重置头等。