Asp.net .NET HttpClient sendAsync()在第二次请求时超时

Asp.net .NET HttpClient sendAsync()在第二次请求时超时,asp.net,iis,httpclient,Asp.net,Iis,Httpclient,我一直在ASP.NET上开发一个类似代理的控制器,它从传入的请求中获取URL,并使用HttpClient调用URL,然后返回文件 此类似代理的控制器的工作方式如下: 执行一个请求时工作正常 在执行多个请求时工作正常,这些响应的内容类型为“application/json”和“xml” 第二次请求时请求超时,执行4次请求时任务取消,这些响应的内容类型为“image/png”。例如: (这4个请求几乎同时发送到控制器) 请求1-0开始,1结束 请求2-在1s开始,在11:00超时并抛出异常(

我一直在ASP.NET上开发一个类似代理的控制器,它从传入的请求中获取URL,并使用HttpClient调用URL,然后返回文件

此类似代理的控制器的工作方式如下:

  • 执行一个请求时工作正常
  • 在执行多个请求时工作正常,这些响应的内容类型为“application/json”和“xml”
  • 第二次请求时请求超时,执行4次请求时任务取消,这些响应的内容类型为“image/png”。例如:

(这4个请求几乎同时发送到控制器)

  • 请求1-0开始,1结束
  • 请求2-在1s开始,在11:00超时并抛出异常(超时为10s),服务器挂起直到超时
  • 请求3-11秒开始,12秒结束
  • 请求4-12秒开始,13秒结束
请忽略帖子情况

控制器

public async Task<FileStreamResult> Proxy(string method, string url, string data = "")
{
    myHttpClient client = new myHttpClient();
    Tuple<MemoryStream,string> result = await client.Proxy(this.Request, method, url).ConfigureAwait(false);
    return File(result.Item1,result.Item2); //file stream and file type
}
公共异步任务代理(字符串方法、字符串url、字符串数据=)
{
myHttpClient=新的myHttpClient();
Tuple result=await client.Proxy(this.Request,method,url).ConfigureAwait(false);
返回文件(result.Item1,result.Item2);//文件流和文件类型
}
HttpClient

public class myHttpClient
{
    private static HttpClient _httpClient;
    static myHttpClient()
    {
        if (_httpClient == null) {
            _httpClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
            _httpClient.Timeout = TimeSpan.FromSeconds(7);
            Log ocLog = new Log();
            ocLog.Write("init client " + ServicePointManager.DefaultConnectionLimit ,false);
        }
    }
    public async Task<Tuple<MemoryStream, string>> Proxy(HttpRequestBase contextRequest, string method, string url)
    {
        var request = new HttpRequestMessage();
        request.RequestUri = new Uri("http://localhost" + url);
        if (method == "GET")
        {
            request.Method = HttpMethod.Get;
            request.Content = null;
        }
        else if (method == "POST")
        {
            request.Method = HttpMethod.Post;
        }

        //copy request header from context.Request
        foreach (string headerName in contextRequest.Headers)
        {
            string[] headerValues = contextRequest.Headers.GetValues(headerName);
            if (!request.Headers.TryAddWithoutValidation(headerName, headerValues))
            {
                request.Content.Headers.TryAddWithoutValidation(headerName, headerValues);
            }
        }

        try
        {
            using (HttpResponseMessage response = await _httpClient.SendAsync(request).ConfigureAwait(false))
            {
                if (response.IsSuccessStatusCode)
                {
                    var contentBytes = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
                    MemoryStream ms = new MemoryStream(contentBytes);
                    return new Tuple<MemoryStream, string>(ms, response.Content.Headers.ContentType.ToString());
                }
                else
                {
                    return null;
                }

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}
公共类myHttpClient
{
私有静态httpclientu HttpClient;
静态myHttpClient()
{
if(_httpClient==null){
_httpClient=newHttpClient(newHttpClientHandler(){UseDefaultCredentials=true});
_httpClient.Timeout=TimeSpan.FromSeconds(7);
Log ocLog=新日志();
Write(“init client”+ServicePointManager.DefaultConnectionLimit,false);
}
}
公共异步任务代理(HttpRequestBase contextRequest、字符串方法、字符串url)
{
var request=new-HttpRequestMessage();
request.RequestUri=新Uri(“http://localhost“+url);
如果(方法==“获取”)
{
request.Method=HttpMethod.Get;
request.Content=null;
}
else if(方法==“POST”)
{
request.Method=HttpMethod.Post;
}
//从context.request复制请求头
foreach(contextRequest.Headers中的字符串headerName)
{
字符串[]headerValues=contextRequest.Headers.GetValues(headerName);
如果(!request.Headers.tryadd未经验证(headerName,headerValue))
{
request.Content.Headers.tryadd未经验证(headerName、headerValue);
}
}
尝试
{
使用(HttpResponseMessage response=wait _httpClient.SendAsync(请求).ConfigureWait(错误))
{
if(响应。IsSuccessStatusCode)
{
var contentBytes=await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
MemoryStream ms=新的MemoryStream(contentBytes);
返回新元组(ms,response.Content.Headers.ContentType.ToString());
}
其他的
{
返回null;
}
}
}
捕获(例外情况除外)
{
掷骰子;
}
}
}
我试过什么

  • 正在检查ServicePointManager.DefaultConnectionLimit。它很大
  • 使用System.net.WebRequest库而不是HttpClient,仍然相同

  • 通过将应用程序池的“最大进程工作人员数”设置为3,问题得到了解决。它成功了

    当web应用程序执行异步代理控制器时,听起来好像有什么东西被锁定了。你试过查看转储文件吗?不,我对转储文件一无所知。我刚刚为我的代理控制器尝试了另一个图像api,所有请求都正常。但是,当代理调用“”时,它无法处理某些请求。当localhost过于频繁地向localhost本身发送请求时,似乎会出现此问题