c# - que - msmq windows 10
¿Hay alguna forma de verificar cuántos mensajes hay en una cola de MSMQ? (9)
El conteo de mensajes en la cola se puede encontrar usando el siguiente código.
MessageQueue messageQueue = new MessageQueue(".//private$//TestQueue");
var noOFMessages = messageQueue.GetAllMessages().LongCount();
Me preguntaba si hay una forma de comprobar programáticamente cuántos mensajes hay en un MSMQ privado o público usando C #. Tengo un código que comprueba si una cola está vacía o no está utilizando el método peek envuelto en un try / catch, pero nunca he visto nada sobre la cantidad de mensajes en la cola. Esto sería muy útil para monitorear si una cola se está respaldando.
El método más rápido que he encontrado para recuperar un conteo de colas de mensajes es usar el método Peek desde el siguiente site :
protected Message PeekWithoutTimeout(MessageQueue q, Cursor cursor, PeekAction action)
{
Message ret = null;
try
{
ret = q.Peek(new TimeSpan(1), cursor, action);
}
catch (MessageQueueException mqe)
{
if (!mqe.Message.ToLower().Contains("timeout"))
{
throw;
}
}
return ret;
}
protected int GetMessageCount(MessageQueue q)
{
int count = 0;
Cursor cursor = q.CreateCursor();
Message m = PeekWithoutTimeout(q, cursor, PeekAction.Current);
{
count = 1;
while ((m = PeekWithoutTimeout(q, cursor, PeekAction.Next)) != null)
{
count++;
}
}
return count;
}
Esto funcionó para mí. Usar un Enumarator para asegurarse de que la cola esté vacía primero.
Dim qMsg As Message '' instance of the message to be picked
Dim privateQ As New MessageQueue(svrName & "/Private$/" & svrQName) ''variable svrnme = server name ; svrQName = Server Queue Name
privateQ.Formatter = New XmlMessageFormatter(New Type() {GetType(String)}) ''Formating the message to be readable the body tyep
Dim t As MessageEnumerator ''declared a enumarater to enable to count the queue
t = privateQ.GetMessageEnumerator2() ''counts the queues
If t.MoveNext() = True Then ''check whether the queue is empty before reading message. otherwise it will wait forever
qMsg = privateQ.Receive
Return qMsg.Body.ToString
End If
No hay API disponible, pero puede usar GetMessageEnumerator2
que es lo suficientemente rápido. Muestra:
MessageQueue q = new MessageQueue(...);
int count = q.Count();
Implementación
public static class MsmqEx
{
public static int Count(this MessageQueue queue)
{
int count = 0;
var enumerator = queue.GetMessageEnumerator2();
while (enumerator.MoveNext())
count++;
return count;
}
}
También probé otras opciones, pero cada una tiene algunas desventajas
- El contador de rendimiento puede arrojar la excepción "Instancia ''...'' no existe en la Categoría especificada."
- Leer todos los mensajes y luego contarlos es realmente lento, también elimina los mensajes de la cola
- Parece que hay un problema con el método
Peek
que arroja una excepción
Puede leer el valor del Contador de rendimiento para la cola directamente desde .NET:
using System.Diagnostics;
// ...
var queueCounter = new PerformanceCounter(
"MSMQ Queue",
"Messages in Queue",
@"machinename/private$/testqueue2");
Console.WriteLine( "Queue contains {0} messages",
queueCounter.NextValue().ToString());
Si necesita un método rápido (25k llamadas / segundo en mi casilla), recomiendo la versión de Ayende basada en MQMgmtGetInfo () y PROPID_MGMT_QUEUE_MESSAGE_COUNT:
para C # https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs
para VB https://gist.github.com/Lercher/5e1af6a2ba193b38be29
El origen probablemente fue http://functionalflow.co.uk/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/ pero no estoy convencido de que esto la implementación desde 2008 funciona más.
Tuve un problema real para que funcionara la respuesta aceptada porque xxx does not exist in the specified Category
error de xxx does not exist in the specified Category
. Ninguna de las soluciones anteriores funcionó para mí.
Sin embargo, simplemente especificar el nombre de la máquina como se muestra a continuación parece solucionarlo.
private long GetQueueCount()
{
try
{
var queueCounter = new PerformanceCounter("MSMQ Queue", "Messages in Queue", @"machineName/private$/stream")
{
MachineName = "machineName"
};
return (long)queueCounter.NextValue();
}
catch (Exception e)
{
return 0;
}
}
Usamos la interoperabilidad MSMQ. Dependiendo de sus necesidades, probablemente pueda simplificar esto:
public int? CountQueue(MessageQueue queue, bool isPrivate)
{
int? Result = null;
try
{
//MSMQ.MSMQManagement mgmt = new MSMQ.MSMQManagement();
var mgmt = new MSMQ.MSMQManagementClass();
try
{
String host = queue.MachineName;
Object hostObject = (Object)host;
String pathName = (isPrivate) ? queue.FormatName : null;
Object pathNameObject = (Object)pathName;
String formatName = (isPrivate) ? null : queue.Path;
Object formatNameObject = (Object)formatName;
mgmt.Init(ref hostObject, ref formatNameObject, ref pathNameObject);
Result = mgmt.MessageCount;
}
finally
{
mgmt = null;
}
}
catch (Exception exc)
{
if (!exc.Message.Equals("Exception from HRESULT: 0xC00E0004", StringComparison.InvariantCultureIgnoreCase))
{
if (log.IsErrorEnabled) { log.Error("Error in CountQueue(). Queue was [" + queue.MachineName + "//" + queue.QueueName + "]", exc); }
}
Result = null;
}
return Result;
}
//here queue is msmq queue which you have to find count.
int index = 0;
MSMQManagement msmq = new MSMQManagement() ;
object machine = queue.MachineName;
object path = null;
object formate=queue.FormatName;
msmq.Init(ref machine, ref path,ref formate);
long count = msmq.MessageCount();
Esto es más rápido de lo que seleccionó uno. Obtienes refferencia de clase MSMQManagement dentro de "C: / Archivos de programa (x86) / Microsoft SDKs / Windows", solo las cejas en esta dirección lo conseguirás. para obtener más detalles, puede visitar http://msdn.microsoft.com/en-us/library/ms711378%28VS.85%29.aspx .