我有一个DataTable,每行有多个TimeStamp(DateTime)列。我想创建一个超时值,所以当TimeStamp传递DateTime.Now-timeoutValue时,它将被取消。当所有TimeStamp值都为空时,该行将被删除。
目前使用定时器和循环实现。很多条目开始变得非常滞后,是否有更自动化的有效方式?表达式还是什么?以下是我的代码剪辑:
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 :(得分:1)
以下是一些小改进的想法,可能会带来显着的改善:
i.Key + ":" + b
)。在内部foreach
内构建一次并将其粘贴在变量中。row[(i.Key + ":" + b)]
)。读一次并将其粘贴在一个变量中,以便您可以多次使用它,而不必每次都进行哈希表查找。if (Timeout == 0) Timeout = 99999;
)。在方法开始时调整一次。DateTime.UtcNow.AddSeconds(-1*Timeout)
)。在方法开始时计算一次。foreach
es中查找。答案 1 :(得分:0)
首先,您可以在此处执行一些操作来提高速度。首先,数据表用于从数据库中提取数据,而不是真正的高端集合。通常,通用列表比数据表快4倍,并且使用的内存要少得多。此外,您的最大时间成本来自第三个循环中间的DateTime.Parse,并在循环中间执行DateTime计算到期时间。它没有出现过期时间是基于记录的原始值,所以你应该在循环开始之前产生一次。
我建议为您的记录格式创建一种数据类型,这样您就可以将记录日期存储为DateTime对象,基本上消耗了首次初始化列表时的转换时间,而不是每次都执行tryparse。因此,使用List来存储数据,您可以简单地执行以下操作:
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
}
}