使用时间戳跟踪并发Web服务请求

时间:2011-04-29 14:51:52

标签: c# asp.net web-services datetime concurrency

我有一个ASP.NET 4.0 Web服务,它接受XML文件的传输。在过去(使用相同Web服务的不同实现),我们使用时间戳跟踪并发性(同时接收/处理的XML文件数)。我已经在新版本的Web服务中复制了这种行为:

在Web Service类的构造函数中,我使用ConnectionStartTime

记录HttpContext.Current.Timestamp
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.0 \ Requests Executing - 此计数器达到峰值52。
  • ASP.NET Apps v4.0 \ Requests Queued - 此计数器最高峰为19。

对我来说,这意味着我应该看到一条点,我们有33条重叠ConnectionStartTimeConnectionEndTime的记录。

2。查询时间戳   - 在this question中,我引用了我正在使用的查询来计算基于ConnectionStartTimeConnectionEndTime的并发传输次数。这些是SQL Server数据库中的datetime个字段。 注意:该问题中的查询是我们过去3年一直用于确定并发性的算法的重新设计版本,因此它可能不是100%正确但是算法的其他实现( Excel宏等已经过验证。

我的问题是这两种方法从不对齐。查询时间戳的最大结果为10,而性能计数器建议最大值应为30+。我很难找到差异所在的位置。我是如何记录我的时间戳的? HttpContext.Current.Timestamp值是否未记录到Web服务的传输开始?

1 个答案:

答案 0 :(得分:0)

使用线程启动会导致数据与ASP.NET计数器之间出现差异(主要是因为您编写线程函数的方式。我会将其更改为:

DateTime EndTime = DateTime.Now
new Thread (() =>
{
    insertIntoDatabase(ConnectionStartTime, ConnectionEndTime=EndTime, xmlFile);
}).Start();
return responseToUser;

不确定它是否是差异的唯一来源,但是使用您的代码,您将测量处理请求所需的时间并启动线程并向数据库发出命令以记录时间。

我的代码仅通过在启动线程之前捕获闭包中的结束时间来测量处理请求的时间。它应该更接近ASP.NET性能计数器。不确定它是否会解释整个差异,但它应该有所帮助。

我同意以前的评论者的意见,你不应该像这样的每个请求开始一个新线程。启动新线程需要时间并且内存密集。如果这是一个高性能应用程序,它肯定会产生影响。使用QueueUserWorkItem会更好,尽管使用ThreadPool会带来一系列的顾虑和限制。

作为最终评论,您正在使用的模式还有一些其他可能的问题,这些问题将随着请求率的增加而出现(排队,并发和瓶颈问题)。我敢打赌,在您当前的实施中,差异会随着请求率而增加。如果这是一个高性能或性能敏感的应用程序,我会使用不同的方法来完全衡量并发性。