我正在编写一个Windows服务,该服务在端口上侦听http消息。这些消息来自RFID标签读取器。侦听部分由一个封闭源API完成,我计划以后在需要时使用我自己的代码进行替换。我有一个事件处理程序,每次阅读器API收到消息时都会触发该事件处理程序。然后,它首先使用实体代码将数据添加到msSQL数据库。
问题是,到目前为止,我探索的两条路线都有很多缺点。
我可以在处理程序方法中创建上下文的本地实例,也可以创建类范围的实例。本地实例的问题在于,它每次运行时都必须缓存数据库(我认为),这似乎要花费大量时间。我使用秒表来计时功能开始到结束的时间。使用本地创建的上下文时,该函数最多可能需要3分钟才能运行。
另一个选择是使用类范围的实例,但是问题在于,缓存没有更新,因此,如果我更改数据库中的某些内容,该方法将看不到它。我在reader类中有一个bool属性,该属性确定是否发送电子邮件通知。
我已经定时了,平均运行时间约为5秒钟。
这是我的缩写eventHandler代码。随着第二条路线。
private DatabaseAPI databaseAPI; //** inherits from dbcontext
private static readonly object HandleMsgLock = new object();
private void handleMsgRecvEvent(string msg)
{
lock (HandleMsgLock)
{
bool error = false;
bool failed = false;
NotifyInfo info = new NotifyInfo();
AlienUtils.ParseNotification(msg, out info);
Reader reader = databaseAPI.GetReader(info.MACAddress);
if (reader != null)
{
Reading reading = new Reading();
if (info.TagList != null)
{
//** fix me, this could use some improvements
for (int i = 0; i < reader.Antennas.Count; i++) //** loop through each antenna
{
reading = new Reading();
reading.Antenna = reader.Antennas.Where(x => x.AntennaNumber == i).SingleOrDefault();
reading.TargetNumOfTags = reading.Antenna.numOfTag;
List<ITagInfo> tagList = info.TagList.Where(x => x.Antenna == i).ToList();
if (tagList.Count == reading.Antenna.numOfTags)
{
log("- - - - - - -" + "\n");
log("TagStatus = OK \n");
reading.Status = Reading.StatusType.Pass;
reading.numOfTagsRead = (short)tagList.Count;
}
else
{
failed = true;
reading.Status = Reading.StatusType.Fail;
reading.numOfTagsRead = (short)tagList.Count;
}
foreach (ITagInfo t in tagList)
{
Tag tag = databaseAPI.GetTag(t.TagID);
if (tag == null)
{
tag = databaseAPI.CreateTag(t.TagID, reading);
}
else
{
//** if tag number does exist add reading to it
tag.Readings.Add(reading);
}
tag.TagID = t.TagID;
reading.Tags.Add(tag);
}
reading.Reader = reader;
reading.TimeStamp = DateTime.Now;
databaseAPI.Readings.Add(reading);
if (failed)
{
handleShoeFailed(reading);
}
else
{
handleShoePassed(reading);
}
log("TagsRead: " + tagList.Count + " out of " + reading.Antenna.numOfTags + "\n");
}//** end for loop
}//** end taglistCount not null
else
{
reading.Antenna = null;
reading.Status = Reading.StatusType.None;
reading.TargetNumOfTags = reader.numOfTags;
reading.Reader = reader;
reading.TimeStamp = DateTime.Now;
databaseAPI.Readings.Add(reading);
failed = true;
handleShoeFailed(reading);
}
databaseAPI.SaveChanges();
}//** end if reader not null
else if (reader == null)
{
log("Received Msg from Unknown Reader: " + info.ReaderName + ", IP: " + info.IPAddress + ", MAC: " + info.MACAddress);
}
}//** end lock
stopWatch.Stop();
log("StopWatch: (" + stopWatch.Elapsed);
log("- - - - - - -" + "\n");
}//** end msg handler
还有其他选择吗?
我从您的帖子中推断出,您正在将此信息存储在关系数据库(可能是MS SQL Server)中,并且消息传输率相当高,并且数据库大小足够大,足以将SQL中的数据检索到dbcontext中。放慢脚步。
有了这些,以及我在C#中看到的逻辑,我将建议一种截然不同的方法:编写SQL存储过程以执行标记为改进的部分中的逻辑。目标应该是处理每条消息仅需要往返数据库服务器一次。我的期望是存储过程应该能够在亚秒级的时间内运行,因为SQL Server本身非常擅长缓存。
这可能需要学习有关Transact-sql的知识,但是我建议您花很多时间来投资它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句