2013-06-05 25 views
0

我有一个DataTable,每行有多个TimeStamp(DateTime)列。我想创建一个超时值,所以当TimeStamp传递DateTime.Now-timeoutValue时,它将被清零。当所有TimeStamp值都为零时,该行被删除。在C#DataTable中每行有多个超时(日期时间)值

它目前使用定时器和循环来实现。有很多条目开始变得非常滞后,是否有更高效的自动化方式?表情或东西?下面是我的代码剪:

public ReadsList(object _readers) 
{ 
    _readers = List of things that add to datatable 
    dataTable = new DataTable(); 
    Timeout = 5; 

    aTimer = new System.Timers.Timer(5000); 
    aTimer.Elapsed += new ElapsedEventHandler(UpdateReads); 
    aTimer.Enabled = true; 
} 

public void Add(object add) 
{ 
    //Checks if object exists, update TimeStamp if so, else, add new row 
} 

private void UpdateReads(object source, ElapsedEventArgs e) 
{ 
    //Clean DataTable 
    foreach (DataRow row in dataTable.Rows.Cast<DataRow>().ToList()) 
    { 
     int p = 0; 
     foreach (var i in _readers) 
     { 
      p += i.Value; 

      for (int b = 1; b <= i.Value; b++) 
      { 
       if (row[(i.Key + ":" + b)] != DBNull.Value) 
       { 
        if (Timeout == 0) 
         Timeout = 99999; 
        if (DateTime.Parse(row[(i.Key + ":" + b)].ToString()) < 
         DateTime.UtcNow.AddSeconds(-1*Timeout)) 
        { 
         row[(i.Key + ":" + b)] = DBNull.Value; 
        }  
       } 
       else 
       { 
         p -= 1; 
       } 
      } 

     } 
      //Remove Row if empty 
      if (p == 0) 
      { 
       row.Delete(); 
       //readCount -= 1; 
      } 
     } 
    dataTable.AcceptChanges(); 
    OnChanged(EventArgs.Empty); 
} 
+0

是否绑定到网格? –

+0

是的,datagridview。 – ktan

回答

1

这里有一对夫妇为小的改进想法可能加起来显著改善:

  1. 你”重新构建列键(i.Key + ":" + b)多次。在内部构建一次foreach并将其粘贴到变量中。
  2. 您正在阅读专栏(row[(i.Key + ":" + b)])多次。只读一次并将其保存在一个变量中,以便您可以多次使用它,而不必每次都进行哈希表查找。
  3. 您正在调整超时(if (Timeout == 0) Timeout = 99999;)多次。在方法开始时调整一次。
  4. 您正在计算超时DateTime(DateTime.UtcNow.AddSeconds(-1*Timeout))多次。在方法开始时计算一次。
  5. 您总是通过字符串查找列值。如果您可以将列序号存储在某个地方并使用它们,则会获得更好的性能。只要确保在方法开始时查看列序号一次,而不是在foreach es中。
  6. 您正在将字符串解析为DateTimes。如果您可以将DateTimes存储在DataTable中,则不必每次都解析。
+0

执行完所有提示后,延迟消失。非常感谢! – ktan

+0

任何想法哪个提示最有效的改进? –

+0

对不起。不确定。我做了一切。 – ktan

0

首先,有一些事情可以做,在这里增加的速度。首先,数据表是为了从数据库中提取数据,而不是真正的高端集合。通常,通用列表比数据表速度快4倍,并且使用的内存要少得多。另外,最大的时间成本来自第三个循环中间的DateTime.Parse权限,并且在循环中间正确执行DateTime计算以计算到期时间。它没有出现过期时间是基于记录的原始值,所以你应该肯定在循环开始之前生成一次。

我建议为您的记录格式创建一个数据类型,这将允许您将记录日期存储为DateTime对象,基本上会在首次初始化列表时花费转换时间,而不是每次都执行tryparse。因此,使用列表来存储数据,那么你可以简单地这样做:

var cutOffTime = DateTime.UtcNow.AddSeconds(-99999); // Do this to save creating it a billion times. 
var totalRecords = AllRecords.Count; // Do this so the value is not re-evaluated 

for(var i=0;i<totalRecords;i++) 
{ 
    var rec = AllRecords[i]; 

    if(rec.TimeThingy1 < CutOffTime && rec.TimeThingy2 < cutOffTime && rec.TimeThingy3 < cutOffTime)  
    { 
     AllRecords.RemoveAt(i); // You could even add this to another list, and remove all at the end, as removing an object from a list during mid-iteration is costly 
    } 
} 
+0

感谢您的提示! – ktan