为什么HttpWebRequest.BeginGetResponse()同步完成?

时间:2012-09-05 14:29:42

标签: c# asp.net .net performance c#-4.0

我正在高负载下测试ASP.NET(.NET 4)Web应用程序,并发现在某些条件下HttpWebRequest.BeginGetResponse()同步完成,不会抛出任何异常。

在高负载的多个ASP.NET线程中运行以下代码后,我发现“WEBR​​EQUEST COMPLETED SYNC!”日志中的消息。

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
var result = webRequest.BeginGetResponse(internalCallback, userState);
if (result.CompletedSynchronously)
{
    Trace.Error("WEBREQUEST COMPLETED SYNC!");
}

注意:

  1. 如果达到线程池容量,则抛出InvalidOperationException
  2. 如果在连接期间发生错误,则抛出相应的异常
  3. 就我而言,没有例外!

    我已经反编译了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);
      }
    }
    

    何时&为什么这可能?

2 个答案:

答案 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#中获取的理由)。