Я пишу процессор очереди ASP.NET. Пользователи войдут в систему и загрузят файлы данных на сайт, а затем нажмите, чтобы начать обработку файлов данных.Передача строк в .NET Windows Service
У меня есть служба Windows в системе, которая ждет, когда элементы поступят в очередь и обработают их. Пока все работает, за исключением того, что элементы в очереди кажутся потерянными. Я считаю, что статические члены теряют объем, но я не уверен, как это исправить.
Я думал о написании вещей в/из файлов, но статус обновляется так часто, что это будет убийца производительности.
Каков наилучший способ получить данные в и из службы?
службы окон выглядит следующим образом:
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
}
}
Может также разместить службу WCF в службе Windows, и иметь ASP.NET приложение вызывает эту услугу. (Более структурированный вариант вашего предложения MSMQ.) – itowlson
Извините, что bNotDoneYet = false отсутствует; Я пропустил это в «дезинфекции» кода. Кроме того, спасибо за образцы синхронизации. В эти дни я не очень много синхронизирую. –
@itowlson: Хороший момент, пропустил это. –