C# Owin中的最大并发请求数

C# Owin中的最大并发请求数,c#,owin,self-hosting,httplistener,servicepointmanager,C#,Owin,Self Hosting,Httplistener,Servicepointmanager,我使用OWIN在控制台应用程序中自行托管一个小型web应用程序 在到达ApicController之前,注册了一个中间件: public class HealthcheckMiddleware : OwinMiddleware { private readonly string DeepHealthEndpointPath = "/monitoring/deep"; private readonly string ShallowHealthEndpointPath = "/mon

我使用OWIN在控制台应用程序中自行托管一个小型web应用程序

在到达ApicController之前,注册了一个中间件:

public class HealthcheckMiddleware : OwinMiddleware
{
    private readonly string DeepHealthEndpointPath = "/monitoring/deep";
    private readonly string ShallowHealthEndpointPath = "/monitoring/shallow";

    public HealthcheckMiddleware(OwinMiddleware next)
        : base(next)
    {
    }

    public async override Task Invoke(IOwinContext context)
    {
        try
        {
            string requestPath = context.Request.Path.Value.TrimEnd('/');
            if (requestPath.Equals(ShallowHealthEndpointPath, StringComparison.InvariantCultureIgnoreCase)
                || requestPath.Equals(DeepHealthEndpointPath, StringComparison.InvariantCultureIgnoreCase))
            {
                context.Response.StatusCode = (int) HttpStatusCode.OK;
            }
            else
            {
                await Next.Invoke(context);
            }
        }
        catch (Exception ex)
        {
            // This try-catch block is inserted for debugging
        }
    }
}
这里Next.Invoke调用控制器方法,该方法基本上是异步地将http请求转发给另一个API,即感兴趣的主线是:

var response = await _httpClient.SendAsync(outgoingRequest);
但是,如果我尝试像这样向API提交10个http请求(不是故意等待它们,因为我想对API进行预发行)

for(int i=0;i<10;i++)
{
var httpRequestMessage=新的httpRequestMessage(HttpMethod.Post,“http://localhost:5558/forwarder");
httpRequestMessage.Content=newStringContent(JsonConvert.SerializeObject(message),Encoding.UTF8,“application/json”);
httpClient.SendAsync(httpRequestMessage);
}
然后立即再提交10个,然后我在HealthcheckMiddleware中的catch块中得到以下异常:

InvalidOperationException:提交响应后无法执行此操作

堆栈跟踪:

at System.Net.HttpListenerResponse.set_ContentLength64(Int64 value)
at Microsoft.Owin.Host.HttpListener.RequestProcessing.ResponseHeadersDictionary.Set(String header, String value)
at Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.Set(String key, String[] value)
at Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.set_Item(String key, String[] value)
at Microsoft.Owin.HeaderDictionary.System.Collections.Generic.IDictionary<System.String,System.String[]>.set_Item(String key, String[] value)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.SetHeadersForEmptyResponse(IDictionary`2 headers)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.SendResponseMessageAsync(HttpRequestMessage request, HttpResponseMessage response, IOwinResponse owinResponse, CancellationToken cancellationToken)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.<InvokeCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at DataRelay.NonGuaranteedDataForwarder.HealthcheckMiddleware.<Invoke>d__3.MoveNext() in C:\_code\DataRelay.NonGuaranteedDataForwarder\HealthcheckMiddleware.cs:line 30
位于System.Net.HttpListenerResponse.set_ContentLength64(Int64值)
位于Microsoft.Owin.Host.HttpListener.RequestProcessing.ResponseHeadersDictionary.Set(字符串头,字符串值)
位于Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.Set(字符串键,字符串[]值)
位于Microsoft.Owin.Host.HttpListener.RequestProcessing.HeadersDictionaryBase.set_项(字符串键,字符串[]值)
位于Microsoft.Owin.HeaderDictionary.System.Collections.Generic.IDictionary.set_项(字符串键,字符串[]值)
位于System.Web.Http.Owin.HttpMessageHandlerAdapter.SetHeadersForEmptyResponse(IDictionary`2头)
在System.Web.Http.Owin.HttpMessageHandlerAdapter.SendResponseMessageAsync(HttpRequestMessage请求、HttpResponseMessageResponse、IOwinResponse owinResponse、CancellationToken CancellationToken)
在System.Web.Http.Owin.HttpMessageHandlerAdapter.d_u0.MoveNext()中
---来自引发异常的上一个位置的堆栈结束跟踪---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中
在System.Runtime.CompilerServices.TaskAwaiter.GetResult()中
在C:\\ u code\DataRelay.nonguarantedDataForwarder\HealthcheckMiddleware.d\\ u 3.MoveNext()中的DataRelay.nonguarantedDataForwarder.HealthcheckMiddleware.cs:第30行
我尝试搜索Stackoverflow和Google,但似乎找不到任何有价值的东西。例如,我发现,但在这里,开发人员在提交请求后读取请求,而我没有这样做

为了以防万一,ApiController中的完整POST方法包含在此处:

    public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
    {
        try
        {
            MetricCollector.RecordIncomingRecommendation();
            using (MetricCollector.TimeForwardingOfRequest())
            {
                string requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
                var data = JObject.Parse(requestContent);
                string payloadType = data.SelectToken("Headers.PayloadType").ToString();
                Log.Logger.Debug("Received message containing {PayloadType}", payloadType);

                var consumersForPayloadType = _consumers.Where(x => x.DataTypes.Contains(payloadType)).ToList();
                if (consumersForPayloadType.Any())
                {
                    Log.Logger.Debug("{NumberOfConsumers} interested in {PayloadType}",
                        consumersForPayloadType.Count,
                        payloadType);
                }
                else
                {
                    Log.Logger.Warning("No consumers are interested in {PayloadType}", payloadType);
                }

                foreach (var consumer in consumersForPayloadType)
                {
                    try
                    {
                        var outgoingRequest = new HttpRequestMessage(HttpMethod.Post, consumer.Endpoint);
                        outgoingRequest.Content = new StringContent(requestContent, Encoding.UTF8,
                            "application/json");

                        foreach (var header in request.Headers)
                        {
                            if (IsCustomHeader(header, _customHeaders))
                                outgoingRequest.Headers.Add(header.Key, header.Value);
                        }

                        if (!string.IsNullOrWhiteSpace(consumer.ApiKey))
                        {
                            request.Headers.Add("Authorization", "ApiKey " + consumer.ApiKey);
                        }

                        var response = await _httpClient.SendAsync(outgoingRequest);
                        if (!response.IsSuccessStatusCode)
                        {
                            Log.Logger.ForContext("HttpStatusCode", response.StatusCode.ToString())
                                .Error("Failed to forward message containing {PayloadType} to {ConsumerEndpoint}",
                                    payloadType, consumer.Endpoint);
                        }
                    }
                    catch (Exception ex)
                    {
                        MetricCollector.RecordException(ex);
                        Log.Logger.Error(ex,
                            "Failed to forward message containing {PayloadType} to {ConsumerEndpoint}", payloadType,
                            consumer.Endpoint);
                    }
                }

                return request.CreateResponse(HttpStatusCode.OK);
            }
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, ex);
        }
    }
公共异步任务Post(HttpRequestMessage请求) { 尝试 { MetricCollector.RecordIncomingRecommension(); 使用(MetricCollector.TimeForwardingFrequest()) { string requestContent=await request.Content.ReadAsStringAsync().ConfigureAwait(false); var data=JObject.Parse(requestContent); 字符串payloadType=data.SelectToken(“Headers.payloadType”).ToString(); Debug(“收到的消息包含{PayloadType}”,PayloadType); var consumersForPayloadType=_consumers.Where(x=>x.DataTypes.Contains(payloadType)).ToList(); if(consumersForPayloadType.Any()) { Log.Logger.Debug(“{NumberOfConsumers}对{PayloadType}感兴趣”, Consumers ForPayloadType.Count, 有效载荷类型); } 其他的 { 警告(“没有消费者对{PayloadType}”感兴趣”,PayloadType); } foreach(consumersForPayloadType中的var使用者) { 尝试 { var outgoingRequest=newhttprequestmessage(HttpMethod.Post,consumer.Endpoint); outgoingRequest.Content=新的StringContent(requestContent,Encoding.UTF8, “应用程序/json”); foreach(request.Headers中的var头) { if(IsCustomHeader(header,_customHeaders)) outgoingRequest.Headers.Add(header.Key,header.Value); } 如果(!string.IsNullOrWhiteSpace(consumer.ApiKey)) { 添加(“授权”、“ApiKey”+消费者.ApiKey); } var response=await\u httpClient.sendsync(outgoingRequest); 如果(!response.issucessStatusCode) { Log.Logger.ForContext(“HttpStatusCode”,response.StatusCode.ToString()) .Error(“无法将包含{PayloadType}的消息转发到{ConsumerEndpoint}”, payloadType,consumer.Endpoint); } } 捕获(例外情况除外) { MetricCollector.RecordException(ex); Log.Logger.Error(例如, “无法将包含{PayloadType}的消息转发到{ConsumerEndpoint}”,PayloadType, 消费者(端点); } } 返回request.CreateResponse(HttpStatusCode.OK); } } 捕获(例外情况除外) { 返回请求.CreateErrorResponse(HttpStatusCode.ServiceUnavailable,ex); } }
尝试删除
.configurewait(false)
所有位置,看看是否有帮助

例如,这里:

string requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);

UPD1:好的。
string requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);