2012-09-05 82 views
5

我正在測試高負載下的ASP.NET(.NET 4)web應用程序,並發現在某些情況下HttpWebRequest.BeginGetResponse()會在不拋出任何異常的情況下同步完成。爲什麼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); 
    } 
} 

當&爲什麼這可能嗎?

+0

看看[AysncCallBack Completed Synchronousously](http://stackoverflow.com/questions/1372053/asynccallback-completedsynchronously)會告訴你什麼是異步循環的共同partter完成同步時你的回調是在同一個線程中。 – Turbot

回答

4

發現本作CompletedSynchronously propperty
使用此屬性來確定異步操作同步完成。例如,如果I/O請求很小,那麼此屬性可以爲異步I/O操作返回true。
HERE

編輯: -我懷疑的響應可能會得到緩存。因此試圖通過使用request.CachePolicy = new HttpRequestCachePolicy(/*caching type*/);

+0

爲什麼投了票? –

+0

有用,但不是答案+1 –

+0

@exacerbatedexpert +1但我希望在有可能的情況下提及反編譯的代碼或帶有細節的文章。 「小」不是一個標準。 –

2

我理解的方式是,在3個方案的完整同步異步方法:

操作可以非常快速地完成 - 因此被同步執行,以避免管理異步操作的開銷。

底層實現 - 或操作系統 - 不支持該場景中的異步編程模型(APM)。

該操作受CPU限制,可以不受阻塞地完成。

(原因摘自c#,簡稱J.Albahari & B.Albahari)。

+0

謝謝。但是我需要更多的細節,特別是HttpWebRequst或代碼鏈接。 –