我正在高负载下测试ASP.NET(.NET 4)Web应用程序,并发现在某些条件下HttpWebRequest.BeginGetResponse()
同步完成,不会抛出任何异常。
在高负载的多个ASP.NET线程中运行以下代码后,我发现“WEBREQUEST COMPLETED SYNC!”日志中的消息。
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
var result = webRequest.BeginGetResponse(internalCallback, userState);
if (result.CompletedSynchronously)
{
Trace.Error("WEBREQUEST COMPLETED SYNC!");
}
注意:
就我而言,没有例外!
我已经反编译了System.Net程序集,发现在某些情况下它确实是可能的。但我不明白这些条件的含义(System.Net.Connection.SubmitRequest(HttpWebRequest request, bool forcedsubmit)
):
if (this.m_Free && this.m_WriteDone && !forcedsubmit && (this.m_WriteList.Count == 0 || request.Pipelined && !request.HasEntityBody && (this.m_CanPipeline && this.m_Pipelining) && !this.m_IsPipelinePaused))
{
this.m_Free = false;
needReConnect = this.StartRequest(request, true);
if (needReConnect == TriState.Unspecified)
{
flag = true;
this.PrepareCloseConnectionSocket(ref returnResult);
this.Close(0);
}
}
何时&为什么这可能?
答案 0 :(得分:4)
为CompletedSynchronously
属性发现了这个
使用此属性确定异步操作是否同步完成。例如,如果I / O请求很小,则此属性可以为异步I / O操作返回true。
HERE
编辑: - 我怀疑响应可能会被缓存。因此,尝试使用request.CachePolicy = new HttpRequestCachePolicy(/*caching type*/);
答案 1 :(得分:2)
我理解的方式是异步方法在3种情况下同步完成:
操作可以非常快速地完成 - 因此同步执行以避免管理异步操作的开销。
底层实现 - 或操作系统 - 在该场景中不支持异步编程模型(APM)。
该操作受CPU限制,可以不受阻塞地完成。
(简称J.Albahari& B.Albahari从c#中获取的理由)。