2016-04-29 2 views
2

Я использую System.Net.HttpListener BeginGetContext/EndGetContext для обработки нескольких HTTP-запросов одновременно. Это хорошо работает на моем 16-ядерном рабочем столе Windows 7 SP1, который одновременно обрабатывает 16 запросов. В Windows Server 2012 R2 16 процессор VM первые два из 20 запросов обрабатываются одновременно, а затем запрос последовательно, например. ответ на третий запрос должен быть отправлен до того, как будет рассмотрен запрос на четвертый запрос.HttpListener Используется асинхронно работает синхронно

Я хотел бы, чтобы сервер обрабатывал запросы аналогично рабочему m/c, т.е. обрабатывать 20 запросов за 8 секунд, а не за 95 секунд.

Следующий журнал показывает поведение на машине 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 запроса откликаются на 46 минут 44 секунды за час, но последний ответ получен через 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); 
     } 
    } 
} 
Смежные вопросы