Mam usługę Windows do przetwarzania komunikatów MSMQ. Opiera się na następującej logice: • W usłudze Windows jest zegar. Co dziesięć minut wykona metodę o nazwie "ProcessMessages".Przetwarzanie komunikatu MSMQ w usłudze Windows
· Wewnątrz tej metody najpierw tworzy listę istniejących identyfikatorów wiadomości, wywołując metodę GetAllMessages kolejki.
· Dla każdego komunikatu, to otrzymuje wiadomość (używając ReceiveById) i zapisuje go do pliku
Czy istnieje lepszy sposób na osiągnięcie przetwarzanie wiadomość?
referencyjny: http://www.switchonthecode.com/tutorials/creating-a-simple-windows-service-in-csharp
Uwaga: Poniższy kod nie daje pożądanego rezultatu, gdy udało mi się jako usługa; jednak nie ma błędu w przeglądarce zdarzeń (nie robię żadnego jawnego rejestrowania). To działało dobrze, gdy była to prosta aplikacja konsolowa. Jak to poprawić? [Teraz działa, kiedy zmieniłem akonto na "Użytkownik", jak opisano w komentarzach poniżej]
Moim obowiązkiem aktuarnym jest przetwarzanie wszystkich wiadomości w określonych godzinach - powiedzmy o 10 rano i 11:00 (każdego dnia). Jakie jest najlepsze podejście do tego?
namespace ConsoleSwitchApp
{
class Program : ServiceBase
{
private static Timer scheduleTimer = null;
static MessageQueue helpRequestQueue = null;
static System.Messaging.XmlMessageFormatter stringFormatter = null;
static void Main(string[] args)
{
ServiceBase.Run(new Program());
}
public Program()
{
this.ServiceName = "LijosService6";
//Queue initialize
helpRequestQueue = new MessageQueue(@".\Private$\MyPrivateQueue", false);
stringFormatter = new System.Messaging.XmlMessageFormatter(new string[] { "System.String" });
//Set Message Filters
MessagePropertyFilter filter = new MessagePropertyFilter();
filter.ClearAll();
filter.Body = true;
filter.Label = true;
filter.Priority = true;
filter.Id = true;
helpRequestQueue.MessageReadPropertyFilter = filter;
//Start a timer
scheduleTimer = new Timer();
scheduleTimer.Enabled = true;
scheduleTimer.Interval = 120000;//2 mins
scheduleTimer.AutoReset = true;
scheduleTimer.Start();
scheduleTimer.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed);
}
protected static void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
ProcessMessages();
}
private static void ProcessMessages()
{
string messageString = "1";
//Message Processing
List<string> messageIdList = GetAllMessageId();
foreach (string messageId in messageIdList)
{
System.Messaging.Message messages = helpRequestQueue.ReceiveById(messageId);
//Store the message into database
messages.Formatter = stringFormatter;
string messageBody = System.Convert.ToString(messages.Body);
if (String.IsNullOrEmpty(messageString))
{
messageString = messageBody;
}
else
{
messageString = messageString + "___________" + messageBody;
}
}
//Write File
string lines = DateTime.Now.ToString();
lines = lines.Replace("/", "-");
lines = lines.Replace(":", "_");
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test" + lines + ".txt");
file.WriteLine(messageString);
file.Close();
}
private static List<string> GetAllMessageId()
{
List<string> messageIdList = new List<string>();
DataTable messageTable = new DataTable();
messageTable.Columns.Add("Label");
messageTable.Columns.Add("Body");
//Get All Messages
System.Messaging.Message[] messages = helpRequestQueue.GetAllMessages();
for (int index = 0; index < messages.Length; index++)
{
string messageId = (System.Convert.ToString(messages[index].Id));
messageIdList.Add(messageId);
messages[index].Formatter = stringFormatter;
messageTable.Rows.Add(new string[] { messages[index].Label, messages[index].Body.ToString() });
}
return messageIdList;
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
}
protected override void OnStop()
{
base.OnStop();
}
}
}
namespace ConsoleSwitchApp
{
[RunInstaller(true)]
public class MyWindowsServiceInstaller : Installer
{
public MyWindowsServiceInstaller()
{
var processInstaller = new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//set the privileges
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.DisplayName = "LijosService6";
serviceInstaller.StartType = ServiceStartMode.Manual;
//must be the same as what was set in Program's constructor
serviceInstaller.ServiceName = "LijosService6";
this.Installers.Add(processInstaller);
this.Installers.Add(serviceInstaller);
}
}
}
To prawdopodobnie problem z uprawnieniami. Spróbuj użyć jednego z innych wbudowanych kont. –
@ M.Babcock Dzięki .. Usługa działała, gdy użyłem ServiceAccount.User i podałem moją nazwę użytkownika i hasło. Jakie jest sugerowane konto tutaj? – Lijo
Gorąco polecam ** nie ** przy użyciu dedykowanego konta użytkownika w środowisku produkcyjnym. Problem jest prawdopodobnie związany z [tym artykułem KB] (http://support.microsoft.com/kb/952569) (chodzi o Vista, ale ten sam problem prawdopodobnie wystąpiłby w 7 i 2008 roku). –