【问题标题】:Why HttpWebRequest.BeginGetResponse() completes synchronously?为什么 HttpWebRequest.BeginGetResponse() 同步完成?
【发布时间】:2012-09-05 14:29:41
【问题描述】:

我正在高负载下测试 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. 如果连接过程中发生错误,则抛出相应的异常

就我而言,没有例外!

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

什么时候以及为什么会这样?

【问题讨论】:

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


【解决方案1】:

CompletedSynchronouslypropperty 找到了这个
使用此属性来确定异步操作是否同步完成。例如,如果 I/O 请求很小,则此属性可以为异步 I/O 操作返回 true。
HERE

编辑:- 我怀疑响应可能会被缓存。因此尝试使用 request.CachePolicy = new HttpRequestCachePolicy(/*caching type*/); 停止缓存响应

【讨论】:

  • 有用,但不是答案+1
  • @exacerbatedexpert +1 但我希望在可能的情况下引用反编译代码或带有详细信息的文章。 “小”不是标准。
  • @ParvSharma 服务器返回 Cache-Control: no-cache 标头。因此,缓存不起作用。
【解决方案2】:

我的理解是异步方法在三种情况下同步完成:

操作可以很快完成 - 因此同步执行以避免管理异步操作的开销。

在这种情况下,底层实现(或操作系统)不支持异步编程模型 (APM)。

该操作受 CPU 限制,可以在不阻塞的情况下完成。

(简而言之,J.Albahari 和 B.Albahari 取自 c# 的原因)。

【讨论】:

  • 谢谢。但我需要更多详细信息,尤其是 HttpWebRequst 或代码链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多