Raman Zhylich
Raman Zhylich

Reputation: 3697

Why HttpWebRequest.BeginGetResponse() completes synchronously?

I'm testing ASP.NET (.NET 4) web-application under high load and have found that under some conditions HttpWebRequest.BeginGetResponse() completes synchronously w/o throwing any exceptions.

After running the following code in multiple ASP.NET threads under high-load I've found "WEBREQUEST COMPLETED SYNC!" message in logs.

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

Pay attention that:

  1. In case thread pool capacity is reached an InvalidOperationException is thrown
  2. In case error occurs during connection corresponding exception is thrown

In my case there are no exceptions!

I've decompiled System.Net assembly and found that it is really possible under some conditions. But I didn't understand what these conditions mean (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);
  }
}

When & why is this possible?

Upvotes: 5

Views: 974

Answers (2)

Parv Sharma
Parv Sharma

Reputation: 12705

found this for CompletedSynchronously propperty
Use this property to determine if the asynchronous operation completed synchronously. For example, this property can return true for an asynchronous I/O operation if the I/O request was small.
HERE

EDIT:- i suspect that the response might be getting cached. therefore try to stop caching of the response by using request.CachePolicy = new HttpRequestCachePolicy(/*caching type*/);

Upvotes: 4

RobH
RobH

Reputation: 3612

The way I understand it is that async methods complete synchronously in 3 scenarios:

The operation could be completed very quickly - and so was executed synchronously to avoid the overhead of managing an asynchronous operation.

The underlying implementation - or operating system - doesn't support the Asynchronous Programming Model (APM) in that scenario.

The operation was CPU-bound and could be completed without blocking.

(reasons taken from c# in a nutshell J.Albahari & B.Albahari).

Upvotes: 2

Related Questions