2016-04-29 27 views
2

System.Net.HttpListener BeginGetContext/EndGetContextを使用して複数のHTTP要求を同時に処理しています。これは、16の要求を同時に処理する私の16コアWindows 7 SP1デスクトップでうまく動作します。 Windows Server 2012 R2 16プロセッサVMでは、最初の2/20の要求が同時に処理され、次に要求が順次処理されます。第3の要求に対する応答は、第4の要求に対する要求が見られる前に送信されなければならない。非同期に使用されるHttpListenerが同期的に動作する

私は、サーバーがデスクトップm/cと同様の方法でリクエストを処理したいと考えています。要求を現在の95秒ではなく8秒で処理します。

次のログは、Windows 7マシン(正常)の動作を示しています。クライアントとサーバーの両方のプロセスは、Windows 7のm/cで実行されます。

これはクライアントのログです。各行は、サーバーによってエコーバックされたクライアントの元の要求と、サーバーによって処理された時刻が追加されたものです。元の要求は、シーケンス番号と、クライアントが要求を行った時刻とを含む。

すべてのリクエストは、その時刻の12:46分に行われ、16時間は12:51までに応答し、最後のリクエストは12:54までに応答することに注意してください。

http://localhost:8894/dostuff?val=1-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=17-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=15-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=2-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=7-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=3-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=13-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=18-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=9-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=14-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=0-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=6-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=10-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=5-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=19-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=11-client-12:46-server-12:51 
http://localhost:8894/dostuff?val=12-client-12:46-server-12:52 
http://localhost:8894/dostuff?val=16-client-12:46-server-12:53 
http://localhost:8894/dostuff?val=8-client-12:46-server-12:53 
http://localhost:8894/dostuff?val=4-client-12:46-server-12:54 

次のログは、Windows Server 2012マシンでの動作を示しています(不良)。クライアントとサーバーの両方のプロセスは、Windows Server 2012 m/cで実行されます。

最初の2つの要求は同時に処理されますが、その後の各要求には5秒間の連続した要求が必要であることに注意してください。

最初の2つの要求は同時に処理されますが、その後の各要求には5秒間の連続した要求が必要であることに注意してください。すべてのリクエストは、時間の経過とともに46分39秒で送信されます。最初の2つの要求は、1時間後の46分44秒に応答されますが、最後の応答は1時間後の48分14秒で受信されます。

http://localhost:8895/dostuff?val=5-client-46:39-server-46:44 
http://localhost:8895/dostuff?val=1-client-46:39-server-46:44 
http://localhost:8895/dostuff?val=2-client-46:39-server-46:49 
http://localhost:8895/dostuff?val=6-client-46:39-server-46:54 
http://localhost:8895/dostuff?val=3-client-46:39-server-46:59 
http://localhost:8895/dostuff?val=4-client-46:39-server-47:4 
http://localhost:8895/dostuff?val=7-client-46:39-server-47:9 
http://localhost:8895/dostuff?val=9-client-46:39-server-47:14 
http://localhost:8895/dostuff?val=8-client-46:39-server-47:19 
http://localhost:8895/dostuff?val=10-client-46:39-server-47:24 
http://localhost:8895/dostuff?val=11-client-46:39-server-47:29 
http://localhost:8895/dostuff?val=12-client-46:39-server-47:34 
http://localhost:8895/dostuff?val=13-client-46:39-server-47:39 
http://localhost:8895/dostuff?val=14-client-46:39-server-47:44 
http://localhost:8895/dostuff?val=15-client-46:39-server-47:49 
http://localhost:8895/dostuff?val=16-client-46:39-server-47:54 
http://localhost:8895/dostuff?val=18-client-46:39-server-47:59 
http://localhost:8895/dostuff?val=17-client-46:39-server-48:4 
http://localhost:8895/dostuff?val=19-client-46:39-server-48:9 
http://localhost:8895/dostuff?val=0-client-46:39-server-48:14 

以下のコードは、いくつかの手がかりを与えるかもしれませんが、私はサーバー上のいくつかのクォータまたはスロットルの問題である可能性が高いと思います。

// SERVER build with "csc program.cs" run as program.exe 
using System; 
using System.Net; 
using System.Text; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     HttpListener listenerLocal = new HttpListener(); 
     listenerLocal.Prefixes.Add("http://*:8895/"); 
     listenerLocal.Start(); 
     while (true) 
     { 
      //var result = listener.BeginGetContext(RequestCallback, listener); 
      var resultLocal = listenerLocal.BeginGetContext((result) => 
      { 
       HttpListener listener = (HttpListener)result.AsyncState; 
       HttpListenerContext context = listener.EndGetContext(result); 
       Thread.Sleep(5000); 
       byte[] buffer = Encoding.UTF8.GetBytes(
        context.Request.Url.OriginalString + string.Format(
        "-server-{0}:{1}", DateTime.Now.Minute, DateTime.Now.Second)); 
       context.Response.ContentLength64 = buffer.Length; 
       System.IO.Stream output = context.Response.OutputStream; 
       output.Write(buffer, 0, buffer.Length); 
       output.Close(); 
      } 
      , listenerLocal); 
      resultLocal.AsyncWaitHandle.WaitOne(); 
     } 
    } 
} 

// CLIENT build with "csc program.cs" run as program.exe 
using System; 
class Program 
{ 
    static void Main(string[] args) 
    { 
     for (int ii = 0; ii < 20; ii++) 
     { 
      var thr = new System.Threading.Thread((ctr) => 
      { 
       var data = new System.Net.WebClient().OpenRead(
        string.Format("http://localhost:8895/dostuff?val={0}-client-{1}:{2}" 
        ,ctr, DateTime.Now.Minute, DateTime.Now.Second)); 
       var reader = new System.IO.StreamReader(data); 
       Console.WriteLine(reader.ReadToEnd()); 
       data.Close(); 
       reader.Close(); 
      }); 
      thr.Start(ii); 
     } 
     Console.ReadLine(); 
    } 

} 

答えて

1

ThreadPool代わりにあなたは、プレーンThread

ご使用のサーバーで使用この

using System; 
using System.Text; 
using System.Net; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     HttpListener listenerLocal = new HttpListener(); 
     listenerLocal.Prefixes.Add("http://*:8895/"); 
     listenerLocal.Start();  

     int count = 0; 
     while (true) 
     { 
      if (count == 20) 
       continue; 

      Interlocked.Increment(ref count); 

      var thr = new Thread(ctr => 
      { 
       var l = ctr as HttpListener; 
       HttpListenerContext context = l.GetContext(); 

       Thread.Sleep(5000); 

       byte[] buffer = Encoding.UTF8.GetBytes(context.Request.Url.OriginalString + string.Format(
        "-server-{0}:{1}", DateTime.Now.Minute, DateTime.Now.Second)); 
       context.Response.ContentLength64 = buffer.Length; 
       System.IO.Stream output = context.Response.OutputStream; 
       output.Write(buffer, 0, buffer.Length); 
       output.Close(); 

       Interlocked.Decrement(ref count); 
      }); 
      thr.Start(listenerLocal); 
     } 
    } 
} 
を使用することができ、バーストタスクのための最善ではありません
関連する問題