.net 什么可能会导致HttpWebRequest调用的巨大开销?
当我使用HttpWebRequest(在Silverlight上)在小块中发送/接收数据时,我测量了“localhost”连接上500字节/秒的非常小的吞吐量。当以大数据块的形式发送数据时,我的速度为2MB/s,比以前快5000倍 有人知道是什么导致了这么大的开销吗 其他信息:.net 什么可能会导致HttpWebRequest调用的巨大开销?,.net,silverlight,performance,http,httpwebrequest,.net,Silverlight,Performance,Http,Httpwebrequest,当我使用HttpWebRequest(在Silverlight上)在小块中发送/接收数据时,我测量了“localhost”连接上500字节/秒的非常小的吞吐量。当以大数据块的形式发送数据时,我的速度为2MB/s,比以前快5000倍 有人知道是什么导致了这么大的开销吗 其他信息: 我正在使用HTTPPOST方法 我在Firefox3.6和InternetExplorer7上都做了性能测试。两者的结果相似 我的CPU只加载了10%(四核,实际上是40%) WebClient显示了类似的结果 更
- 我正在使用HTTPPOST方法
- 我在Firefox3.6和InternetExplorer7上都做了性能测试。两者的结果相似
- 我的CPU只加载了10%(四核,实际上是40%)
- WebClient显示了类似的结果
public class HttpCommChannel
{
public delegate void ResponseArrivedCallback(object requestContext, BinaryDataBuffer response);
public HttpCommChannel(ResponseArrivedCallback responseArrivedCallback)
{
this.responseArrivedCallback = responseArrivedCallback;
this.requestSentEvent = new ManualResetEvent(false);
this.responseArrivedEvent = new ManualResetEvent(true);
}
public void MakeRequest(object requestContext, string url, BinaryDataBuffer requestPacket)
{
responseArrivedEvent.WaitOne();
responseArrivedEvent.Reset();
this.requestMsg = requestPacket;
this.requestContext = requestContext;
this.webRequest = WebRequest.Create(url) as HttpWebRequest;
this.webRequest.AllowReadStreamBuffering = true;
this.webRequest.ContentType = "text/plain";
this.webRequest.Method = "POST";
this.webRequest.BeginGetRequestStream(new AsyncCallback(this.GetRequestStreamCallback), null);
this.requestSentEvent.WaitOne();
}
void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
System.IO.Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);
postStream.Write(requestMsg.Data, 0, (int)requestMsg.Size);
postStream.Close();
requestSentEvent.Set();
webRequest.BeginGetResponse(new AsyncCallback(this.GetResponseCallback), null);
}
void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
Dim.Ensure(streamResponse.CanRead);
byte[] readData = new byte[streamResponse.Length];
Dim.Ensure(streamResponse.Read(readData, 0, (int)streamResponse.Length) == streamResponse.Length);
streamResponse.Close();
response.Close();
webRequest = null;
responseArrivedEvent.Set();
responseArrivedCallback(requestContext, new BinaryDataBuffer(readData));
}
HttpWebRequest webRequest;
ManualResetEvent requestSentEvent;
BinaryDataBuffer requestMsg;
object requestContext;
ManualResetEvent responseArrivedEvent;
ResponseArrivedCallback responseArrivedCallback;
}
我使用此代码将数据来回发送到HTTP服务器
更新:经过广泛的研究,我得出结论。我怀疑您的问题只是延迟。任何消息都需要一段时间才能到达服务器,并进行解析和处理,生成响应,而响应需要一段时间才能返回到客户端,并被解析为可用的响应。你的表现很可能是由往返时间决定的 基本上,任何跨越通信边界的接口——无论是进程间还是机器间——都应该是“粗块”而不是“闲聊”。在每个请求中发送尽可能多的信息,并在响应中获取尽可能多的数据。在同一台机器上,这可能看起来微不足道,但我看到应用程序服务器的性能提高了十倍,方法是在工作进程中批量执行命令,而不是针对每个命令从工作进程回调到主服务器进程
您确实回答了自己的问题,指出当您使用大的块大小时,您会获得更好的性能。正如Mike Dimmick在其回答中提到的,延迟问题可能会导致问题,但是,除了在数据有效负载非常小的情况下出现延迟问题外,还要分配线程以执行(即使使用线程池)与批量有效负载路由相比,连接建立后所花费的时间占总时间的百分比要大得多。很可能您看到了Nagle算法的效果,请尝试:
this.webRequest.UseNagleAlgorithm.ServicePoint = false;
此外,Expect100Continue“握手”与soap服务调用性能相关:
this.webRequest.Expect100Continue.ServicePoint = false;
乌德帕特:
刚刚意识到ServicePoint在Compact框架中不可用。但是,您可以通过以下方式证明这一点:
ServicePointManager.UseNagleAlgorithm = false
或者更改应用程序配置文件中的相关设置,或者silverlight中的任何等效设置?请显示一些代码-如果不看到代码,很难判断发生了什么。“使用大的块大小”:我不理解的是系数5000,对我来说似乎高得离谱。“在CF中不可用”:CF是什么意思?对不起,我把Compact Framework和Silverlight混淆了。因此,在使用GetResponse()发出http请求之前,我不确定ServicePoint对象是否在silverlight中可用。在CF中,该对象创建较晚,以减少资源使用。虽然我无法测试它,但您可能对Nagle延迟的看法是正确的。我没有想到这一点。遗憾的是,看起来UseNagleAlgorithm在Silverlight中不可用。无论如何,非常感谢您的回复!至少我现在明白了问题所在。哇,这让我想起了往事。我们12年前就遇到了这个问题;我们会以16赫兹的频率发送环境更新数据包,但很惊讶地看到它们以4赫兹的频率一组四个地出现。幸运的是,我们在Linux上使用C++,所以有一个标志,我们可以传递到套接字关闭这个。我们不知道它被称为“Nagle算法”,但我们总是称它为“数据包合并”