ASP.NET 큐 프로세서를 작성하고 있습니다. 사용자는 로그인하고 데이터 파일을 사이트에 업로드 한 다음을 클릭하여 데이터 파일 처리를 시작합니다.문자열을 .NET Windows 서비스에 전달
대기열에 항목이 도착할 때까지 기다리고 대기열을 처리하는 시스템에 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
}
}
또한 Windows 서비스에서 WCF 서비스를 호스팅하고, ASP.NET을 수 앱에서 해당 서비스를 호출합니다. (MSMQ 제안에 대한 구조화 된 변형입니다.) – itowlson
bNotDoneYet = false가 누락 된 점에 대해 사과드립니다. 나는 코드의 'sanitization'에서 그것을 놓쳤다. 또한 동기화 샘플을 보내 주셔서 감사합니다. 요즘에는 동기화를 많이하지 않습니다. –
@itowlson : 좋은 지적입니다. –