gpt4 book ai didi

asp.net - 向 localhost 发出许多 Web 请求时,HttpClient 卡在 GetAsync 上

转载 作者:行者123 更新时间:2023-12-01 18:43:20 26 4
gpt4 key购买 nike

我在调用 api/Values/Test?times={x} 时遇到以下问题。当 x 时不会出现此问题是1、2、...,但是当达到9、10等时Web请求就会超时。如您所见,Test端点将向 EndPoint 发出 Web 请求x次(请原谅无意义的方法体,它们在实践中会做更有意义的事情):

public class ValuesController:  System.Web.Http.ApiController
{
[HttpGet]
public async Task<object> Test(int times)
{
var tasks = new List<Task<int>>();
for (var i = 0; i < times; i++)
{
//Make web request to the `EndPoint` method below
var task = new ApiRequestBuilder<int>("https://localhost:44301/api/Values/EndPoint")
.GetAsync();
tasks.Add(task);
}
return await Task.WhenAll(tasks.ToArray());
}

[HttpGet]
[CustomAuthorise]//This makes a web request to `AuthEndPoint` (below)
public int EndPoint()
{
return 0;
}

[HttpGet]
public bool AuthEndPoint()
{
return true;
}
}

(注意请参阅下面的 ApiRequestBuilder 是什么)

然而,问题不在于 EndPoint被击中x次,是 CustomAuthorise属性,这会发出进一步的 Web 请求,这就是问题所在:

public class CustomAuthoriseAttribute : System.Web.Http.AuthorizeAttribute
{
public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var result = await this.AuthoriseAsync(actionContext);
if (!result)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
}
}

public virtual async Task<bool> AuthoriseAsync(HttpActionContext context)
{
//***********HANGING HERE************
//var result= await new ApiRequestBuilder<bool>("https://www.example.com")
var result= await new ApiRequestBuilder<bool>("https://localhost:44301/Values/AuthEndPoint")
.GetAsync();

return result;
}
}

如你所见,我已经注释掉了路线"https://www.example.com" 。当我将 url 设置为不是 localhost 的内容时,无论我想要多少,a 都可以向该 Web 请求发送垃圾邮件(通过将 x 设置为一个较大的数字)。

ApiRequestBuilder是通过 System.Net.Http.HttpClient 发出网络请求的帮助程序(版本 4.0.0.0 , .NETframework v4.5.1 ),它将响应序列化为您提供的通用类型参数。

public class ApiRequestBuilder<T> 
{
protected string Url => Uri?.AbsoluteUri;
protected Uri Uri;
protected readonly HttpClient Client;

public ApiRequestBuilder(string url)
{
Uri = new Uri(url);
var client = new HttpClient()
{
BaseAddress = this.Uri,
//Set timeout so replicating this issue itn't a pain
Timeout = TimeSpan.FromSeconds(5)
};
this.Client = client;
}

public async Task<T> GetAsync()
{
var response = await this.Client.GetAsync(this.Url);
var responseContent = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
}

我尝试过的事情:

  • 有一个using每次使用 HttpClient 的声明在ApiRequestBuilder - 仍然挂起。

  • 等待每个 TaskValuesController.Test 的 for 循环中- 这有效,但不能解决我的问题,因为在实践中我试图模拟使用我的自定义身份验证属性的并发性。

潜在有用:

  • 我正在端口 44301 上运行本地 IIS ,最大并发连接数非常大 - 4294967295。

  • 就像我说的,将网址从 localhost 更改为类似 example.com授权时修复问题,从而将问题隔离到我的本地设置出现问题

有谁知道为什么在授权属性中使用 Web 请求似乎会因使用 localhost 的并发而挂起而不是使用广阔世界中的网址?

更新

正在运行netstat -n在挂起时(我删除了超时,以便我可以查看 TCP 连接正在做什么)。对于每个看似被阻止的正在进行的网络请求,我有以下内容:

Proto  Local Address          Foreign Address        State
TCP [::1]:44301 [::1]:44728 CLOSE_WAIT
TCP [::1]:44728 [::1]:44301 FIN_WAIT_2

this的帮助下,看起来服务器已要求客户端退出,客户端也承认了这一点,但它们都挂起(客户端没有关闭?)。

最佳答案

可能是创建了太多客户端并导致套接字耗尽的已知问题。

引用YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE

使用单个静态客户端应该可以解决这个问题

public class ApiRequestBuilder<T>  {
protected string Url => Uri?.AbsoluteUri;
protected Uri Uri;
static HttpClient Client = new HttpClient() {
//Set timeout so replicating this issue itn't a pain
Timeout = TimeSpan.FromSeconds(5)
};

public ApiRequestBuilder(string url) {
Uri = new Uri(url);
}

public async Task<T> GetAsync() {
var response = await Client.GetAsync(this.Url);
var result = await response.Content.ReadAsAsync<T>();
return result;
}
}

关于asp.net - 向 localhost 发出许多 Web 请求时,HttpClient 卡在 GetAsync 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52776100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com