5

高負荷で 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!");
}

次の点に注意してください。

  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);
  }
}

いつ、なぜこれが可能ですか?

4

2 に答える 2

4

これはプロパティで見つかりました。このCompletedSynchronouslyプロパティ
を使用して、非同期操作が同期的に完了したかどうかを判断します。たとえば、このプロパティは、I/O 要求が小さい場合、非同期 I/O 操作に対して true を返すことができます。
ここ

編集:-応答がキャッシュされている可能性があると思われます。したがって、次を使用して応答のキャッシュを停止してみてくださいrequest.CachePolicy = new HttpRequestCachePolicy(/*caching type*/);

于 2012-09-05T14:40:46.303 に答える
2

私が理解している方法は、非同期メソッドが 3 つのシナリオで同期的に完了することです。

操作は非常に迅速に完了する可能性があるため、非同期操作を管理するオーバーヘッドを回避するために同期的に実行されました。

基になる実装 (またはオペレーティング システム) は、そのシナリオでは非同期プログラミング モデル (APM) をサポートしていません。

操作は CPU バウンドであり、ブロックせずに完了することができました。

(一言で言えば、J.Albahari と B.Albahari の c# から得た理由)。

于 2012-09-05T14:36:52.190 に答える