I am writing a windows service that listens on a port for http messages. These messages are from a RFID tag reader. The listening portion is done by a closed source API that I plan on replacing later if need be with my own code. I have an eventHandler that is fired every time the reader API receives a message. It then added the data to a msSQL database, using entity code first.
The problem is the two routes I have explored so far have major draw backs.
I can create a local instance of my context in the handler method, or I can create a class wide instance. The problem with the local instance is that it has to cache the database (I think) every time it runs which seems to take a considerable amount of time. I've used a stop watch to time the function start to end. With the context created locally it can take up to 3 minutes for the function to run.
The other option is to use a class wide instance but the problem with that is, that the cache isn't updated so that if I change something in the database the method won't see it. I have a bool property in the reader class that that determines whether to send an email notification or not.
I've timed this and it averages about 5 seconds to run.
Here is my abbreviated eventHandler code. With the second route.
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
Is there another option?