I am writing a ASP.NET queue processor. Users will login and upload data files to the site, and then click to start processing the data files.
I have a Windows Service on the system that waits for items to arrive in the queue and processes them. So far everything works except the items in the queue seem to get lost. I believe the static members are losing scope, but I'm not sure how to fix it.
I thought about writing things to/from files, but the Status updates so often it would be a performance killer.
What's the best way to get data in and out of the service?
The Windows service is as follows:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
namespace MyMonitorService
{
public class MyMonitor : ServiceBase
{
#region Members
private System.Timers.Timer timer = new System.Timers.Timer();
private static Queue<String> qProjectQueue = new Queue<String>();
private static Mutex mutexProjectQueue = new Mutex(false);
private Boolean bNotDoneYet = false;
#endregion
#region Properties
public static String Status { get; private set; }
#endregion
#region Construction
public MyMonitor ()
{
this.timer.Interval = 10000; // set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
Status = String.Empty;
}
#endregion
private void timer_Elapsed (object sender, ElapsedEventArgs e)
{
try
{
if (!this.bNotDoneYet)
{
this.bNotDoneYet = true;
for (;;)
{
MyMonitor.mutexProjectQueue.WaitOne();
if (MyMonitor.qProjectQueue.Count == 0)
{
EventLog.WriteEntry("MyMonitor", "The queue is empty", EventLogEntryType.Information);
break;
}
String strProject = MyMonitor.qProjectQueue.Dequeue();
EventLog.WriteEntry("MyMonitor", String.Format("The project {0} was dequeued", strProject), EventLogEntryType.Information);
MyMonitor.mutexProjectQueue.ReleaseMutex();
// Do something that updates MyMonitor.Status up to thousands of times per minute
}
}
this.bNotDoneYet = false;
}
catch (Exception ex)
{
EventLog.WriteEntry("MyMonitor", ex.Message, EventLogEntryType.Error);
}
}
public static void EnqueueProjects (params String[] astrProjects)
{
try
{
String strMessage = String.Format("The following projects were added to the queue:\n{0}", String.Join("\n", astrProjects));
EventLog.WriteEntry("MyMonitor", strMessage, EventLogEntryType.Information);
if (astrProjects == null)
return;
MyMonitor.mutexProjectQueue.WaitOne();
foreach (String strProject in astrProjects)
MyMonitor.qProjectQueue.Enqueue(strProject);
MyMonitor.mutexProjectQueue.ReleaseMutex();
}
catch (Exception e)
{
EventLog.WriteEntry("MyMonitor", e.Message, EventLogEntryType.Error);
}
}
#region Service Start/Stop
[STAThread]
public static void Main ()
{
ServiceBase.Run(new MyMonitor());
}
protected override void OnStart (string[] args)
{
try
{
EventLog.WriteEntry("MyMonitor", "MyMonitor Service Started", EventLogEntryType.Information);
this.timer.Enabled = true;
}
catch (Exception e)
{
EventLog.WriteEntry("MyMonitor", e.Message, EventLogEntryType.Error);
}
}
protected override void OnStop ()
{
try
{
EventLog.WriteEntry("MyMonitor", "MyMonitor Service Stopped", EventLogEntryType.Information);
this.timer.Enabled = false;
}
catch (Exception e)
{
EventLog.WriteEntry("MyMonitor", e.Message, EventLogEntryType.Error);
}
}
#endregion
}
}