我有一个ASP。接受XML文件传输的。NET 4.0 Web服务。在过去(使用同一web服务的不同实现),我们使用时间戳跟踪并发性(同时接收/处理的XML文件的数量)。我在新版本的web服务中复制了这种行为:
在Web Service类的构造函数中,我使用HttpContext.Current.Timestamp
ConnectionStartTime
public class MyWebService : System.Web.Services.WebService
{
public MyWebService()
{
ConnectionStartTime = HttpContext.Current.Timestamp
}
}
处理完WebMethod
中的XML文件后,我将该文件插入数据库(记录ConnectionEndTime
)并将响应返回给用户。我在一个新的Thread
中执行数据库插入,这样最终用户就不必等待插入发生来接收他们的响应。
new Thread (() =>
{
insertIntoDatabase(ConnectionStartTime, ConnectionEndTime=Datetime.Now, xmlFile);
}).Start();
return responseToUser;
现在我正在尝试测量我们使用两种方法达到了多少并发XML传输:
1。性能计数器
- ASP。. NET Apps v4.0Requests正在执行-此计数器的峰值为52.
- ASP。. NET Apps v4.0请求队列-此计数器的峰值为19.
对我来说,这意味着我应该看到我们有33条记录重叠ConnectionStartTime
和ConnectionEndTime
。
2。查询时间戳在这个问题中,我引用了我用来计算基于ConnectionStartTime
和ConnectionEndTime
的并发传输数的查询。这些是SQL Server数据库中的datetime
字段。注意:该问题中的查询是我们过去3年来一直使用的算法的重制版本,因此它可能不是100%正确,但该算法的其他实现(Excel宏等)已经过验证。
我的问题是这两个方法永远不会对齐。查询时间戳的最大结果是10,而性能计数器建议的最大值应该是30+。我很难找到差异在哪里。我记录时间戳的方式有问题吗?HttpContext.Current.Timestamp
值是否不记录向web服务传输的开始?
使用线程启动将导致您的数据和ASP. js之间的差异。. NET计数器(主要是因为您编写线程函数的方式。我会把它改成:
DateTime EndTime = DateTime.Now
new Thread (() =>
{
insertIntoDatabase(ConnectionStartTime, ConnectionEndTime=EndTime, xmlFile);
}).Start();
return responseToUser;
不确定这是否是差异的唯一来源,但是使用您的代码,您正在测量处理请求和启动线程并向数据库发出命令以记录时间所需的时间。
我的代码仅通过在启动线程之前捕获闭包中的结束时间来测量处理请求的时间。它应该更接近ASP。. NET性能计数器。我不确定它是否能解释全部的差异,但它应该有所帮助。
我同意之前的评论,你不应该像这样每个请求都开始一个新的线程。启动新线程需要时间,并且非常占用内存。如果这是一个高性能应用程序,它肯定会产生影响。使用QueueUserWorkItem会更好,尽管使用ThreadPool有它自己的一组关注点和限制。
作为最后的注释,您正在使用的模式有一些其他潜在的陷阱,会随着请求率的增加而出现(队列、并发性和瓶颈问题)。我敢打赌,在您当前的实现中,这种差异会随着请求率的增加而增加。如果这是一个高性能或对性能敏感的应用程序,我会使用完全不同的方法来度量并发性。