我正在使用System.Net.HttpListener BeginGetContext / EndGetContext来同时处理多个http请求。这适用于我的16核Windows 7 SP1桌面,它同时处理16个请求。在Windows Server 2012 R2 16处理器VM上,同时处理20个请求中的前2个请求,然后按顺序处理请求,例如,必须在查看第四个请求的请求之前发送第三个请求的响应。
我希望服务器以类似于桌面m / c的方式处理请求。在8秒内处理20个请求而不是当前的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上运行。
请注意,前两个请求会同时处理,但每个后续请求需要连续5秒。
请注意,前两个请求会同时处理,但每个后续请求需要连续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();
}
}
答案 0 :(得分: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);
}
}
}