什么是HttpTransportElement的RequestInitializationTimeout?MSDN说:
获取或设置时间跨度,该时间跨度指定在超时之前请求初始化必须完成的时间.
究竟什么是"请求初始化"?为什么我要设置此属性?
没有关于RequestInitializationTimeout.
源代码中有SharedHttpTransportManager.IsCompatible关于RequestInitializationTimeout检查的注释:
Run Code Online (Sandbox Code Playgroud)// We are NOT checking the RequestInitializationTimeout here since the HttpChannelListener should be handle them // individually. However, some of the scenarios might be impacted, e.g., if we have one endpoint with high RequestInitializationTimeout // and the other is just normal, the first endpoint might be occupying all the receiving loops, then the requests to the normal endpoint // will experience timeout issues. The mitigation for this issue is that customers should be able to increase the MaxPendingAccepts number.
如果我们检查TimeoutException它分配给与内部requestException一起传递HttpRequestContext.SetMessage(message, requestException)的OnParseComplete,我们可以看到:
// We are NOT checking the RequestInitializationTimeout here since the HttpChannelListener should be handle them
// individually. However, some of the scenarios might be impacted, e.g., if we have one endpoint with high RequestInitializationTimeout
// and the other is just normal, the first endpoint might be occupying all the receiving loops, then the requests to the normal endpoint
// will experience timeout issues. The mitigation for this issue is that customers should be able to increase the MaxPendingAccepts number.
Run Code Online (Sandbox Code Playgroud)
并且关于异常消息是:SR.RequestInitializationTimeoutReached System.Private.ServiceModel
The initialization process of the request message timed out after {0}. To increase this quota, use the '{1}' property on the '{2}'.
Run Code Online (Sandbox Code Playgroud)
这将被格式化为这样的:
The initialization process of the request message timed out after 00:00:10. To increase this quota, use the 'RequestInitializationTimeout' property on the 'HttpTransportBindingElement'.
Run Code Online (Sandbox Code Playgroud)
如果我们按照源代码,我们可以在里面找到它的用法EmptyHttpPipeline。
EmptyHttpPipeline.EmptyHttpPipeline如果有一个RequestInitializationTimeout TimeSpan(而不是默认00:00:00禁用它),一个IOThreadTimer设置与dueTime设置到TimeSpan蜱,在回调(实际对象)作为。OnRequestInitializationTimeout ActionthisEmptyHttpPipelinecallbackState
new TimeoutException(SR.GetString(
SR.RequestInitializationTimeoutReached,
this.HttpRequestContext.Listener.RequestInitializationTimeout,
"RequestInitializationTimeout",
typeof(HttpTransportBindingElement).Name))
Run Code Online (Sandbox Code Playgroud)
当它的检查EmptyHttpPipeline.OnParseComplete方法是由试图取消被叫requestInitializationTimer。如果有一个计时器并且它之前被取消或过期,它会创建一个TimeoutException它分配给requestException它的 ,它与HttpPipeline.HttpRequestContext.SetMessage一起传递给message:
The initialization process of the request message timed out after {0}. To increase this quota, use the '{1}' property on the '{2}'.
Run Code Online (Sandbox Code Playgroud)
该OnParseComplete方法被称为内EnqueueMessageAsyncResult.CompleteParseAndEnqueue使用内部的方法。该调用时被创建对象和它终止内部。HandleParseIncomingMessage AsyncCallbackEnqueueMessageAsyncResult.EndEnqueueMessageAsyncResultEmptyHttpPipeline.BeginProcessInboundRequestEmptyHttpPipeline.EndProcessInboundRequest
BeginProcessInboundRequest 和 EndProcessInboundRequestThe initialization process of the request message timed out after 00:00:10. To increase this quota, use the 'RequestInitializationTimeout' property on the 'HttpTransportBindingElement'.
Run Code Online (Sandbox Code Playgroud)
EnqueueMessageAsyncResult.CompleteParseAndEnqueueif (this.httpRequestContext.Listener.RequestInitializationTimeout != HttpTransportDefaults.RequestInitializationTimeout)
{
this.requestInitializationTimer = new IOThreadTimer(onRequestInitializationTimeout, this, false);
this.requestInitializationTimer.Set(this.httpRequestContext.Listener.RequestInitializationTimeout);
}
Run Code Online (Sandbox Code Playgroud)
正在使用该CancelRequestInitializationTimer方法对其进行检查,如果没有设置计时器,则仅返回 true;如果它之前被取消,它返回false,否则它调用IOThreadTimer.Cancel方法来检查并返回true,如果它被取消,或者如果计时器过期则返回false 。
EmptyHttpPipeline.CancelRequestInitializationTimerprotected override void OnParseComplete(Message message, Exception requestException)
{
if (!this.CancelRequestInitializationTimer() && requestException == null)
{
requestException = FxTrace.Exception.AsError(new TimeoutException(SR.GetString(
SR.RequestInitializationTimeoutReached,
this.HttpRequestContext.Listener.RequestInitializationTimeout,
"RequestInitializationTimeout",
typeof(HttpTransportBindingElement).Name)));
}
this.HttpRequestContext.SetMessage(message, requestException);
}
Run Code Online (Sandbox Code Playgroud)
在OnRequestInitializationTimeout方法内部,我们可以看到它取消了HttpPipeline中止的HttpPipeline.httpRequestContext:
EmptyHttpPipeline.OnRequestInitializationTimeoutinternal override IAsyncResult BeginProcessInboundRequest(
ReplyChannelAcceptor replyChannelAcceptor,
Action dequeuedCallback,
AsyncCallback callback,
object state)
{
this.TraceBeginProcessInboundRequestStart();
return new EnqueueMessageAsyncResult(replyChannelAcceptor, dequeuedCallback, this, callback, state);
}
internal override void EndProcessInboundRequest(IAsyncResult result)
{
// It will trigger HandleParseIncomingMessage AsyncCallback,
// that will call CompleteParseAndEnqueue
EnqueueMessageAsyncResult.End(result);
this.TraceProcessInboundRequestStop();
}
Run Code Online (Sandbox Code Playgroud)
HttpPipeline.Cancelvoid CompleteParseAndEnqueue(IAsyncResult result)
{
using (DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.BoundOperation(this.CallbackActivity) : null)
{
Exception requestException;
Message message = this.pipeline.EndParseIncomingMesssage(result, out requestException);
if ((message == null) && (requestException == null))
{
throw FxTrace.Exception.AsError(
new ProtocolException(
SR.GetString(SR.MessageXmlProtocolError),
new XmlException(SR.GetString(SR.MessageIsEmpty))));
}
// Here the EmptyHttpPipeline.OnParseComplete is being invoked
this.pipeline.OnParseComplete(message, requestException);
this.acceptor.Enqueue(this.pipeline.HttpRequestContext, this.dequeuedCallback, true);
}
}
Run Code Online (Sandbox Code Playgroud)
EmptyHttpPipeline对象?EmptyHttpPipeline如果我们transportIntegrationHandler = null使用HttpPipeline.CreateHttpPipeline接受 aTransportIntegrationHandler并且没有的静态设置,我们会得到一个HttpRequestContext.HttpMessagesSupported:
protected bool CancelRequestInitializationTimer()
{
if (this.requestInitializationTimer == null)
{
return true;
}
if (this.requestInitializationTimerCancelled)
{
return false;
}
bool result = this.requestInitializationTimer.Cancel();
this.requestInitializationTimerCancelled = true;
return result;
}
Run Code Online (Sandbox Code Playgroud)
在CreateHttpPipeline被称为上HttpRequestContext.InitializeHttpPipeline:
HttpRequestContext.InitializeHttpPipelinestatic void OnRequestInitializationTimeout(object obj)
{
Fx.Assert(obj != null, "obj should not be null.");
HttpPipeline thisPtr = (HttpPipeline)obj;
thisPtr.Cancel();
}
Run Code Online (Sandbox Code Playgroud)
在使用内部调用HttpRequestContext requestContext(在HttpContextReceivedAsyncResult构造函数中传递)HttpContextReceivedAsyncResult<TListenerChannel>.ProcessHttpContextAsyncHttpChannelListener<TListenerChannel>.transportIntegrationHandler
HttpContextReceivedAsyncResult<TListenerChannel>.ProcessHttpContextAsyncpublic virtual void Cancel()
{
this.httpRequestContext.Abort();
}
Run Code Online (Sandbox Code Playgroud)
所有这些都让我们得出结论,当 aHttpPipeline创建时没有 aTransportIntegrationHandler并且没有HttpMessagesSupportedfor HttpRequestContext,那么新EmptyHttpPipeline对象将为/设置超时(如果RequestInitializationTimeout设置), 并在使用inside设置消息时设置异常。BeginProcessInboundRequestEndProcessInboundRequestEmptyHttpPipeline.HttpRequestContext.SetMessageEmptyHttpPipeline.OnParseComplete
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |