Zastanawiam się, czy istnieje sposób programowo sprawdzić, ile wiadomości są w prywatnym lub publicznym MSMQ przy użyciu C#? Mam kod, który sprawdza, czy kolejka jest pusta lub nie używa metody peek owiniętej w try/catch, ale nigdy nie widziałem nic o wyświetlaniu liczby wiadomości w kolejce. Byłoby to bardzo pomocne w monitorowaniu, jeśli trwa tworzenie kopii zapasowej kolejki.Czy istnieje sposób sprawdzenia, ile wiadomości znajduje się w kolejce MSMQ?
Odpowiedz
Możesz przeczytać wartość licznika wydajności dla kolejki bezpośrednio z .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());
Używamy MSMQ Interop. W zależności od potrzeb można prawdopodobnie uprościć następująco:
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;
}
Dzięki, ale gdzie jest MSMQ.ManagementClass? Czytałem w innym poście, że musisz dołączyć bibliotekę COM o nazwie "MSMQ 3.0", ale nie widzę tego na karcie Com (przy użyciu .NET 3.5.) – Justin
Czy masz Interop.MSMQ.dll w dowolnym miejscu na komputerze? Mamy go w naszej kolekcji montażowej. –
Nie Nie mam tego, ani nie widzę nigdzie, aby pobrać go online. – Justin
Najszybszy sposób znalazłem się odzyskać licznik kolejki wiadomości jest użycie metody Peek z poniższego 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;
}
System.Messaging.MessageQueueException. MQ_ACTION_PEEK_NEXT Przeznaczone do MQReceiveMessage nie mogą być stosowane w miejscu kursora w System.Messaging.MessageQueue.ReceiveCurrent (timeout TimeSpan, działanie Int32, CursorHandle kursora filtr MessagePropertyFilter, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType) w System.Messaging.MessageQueue.Peek (Limit czasu TimeSpan, kursor kursora, akcja PeekAction) – Justin
Używamy tej dokładnej metody i stwierdzamy, że metoda GetMessageCount zawodzi, ponieważ przegląda się, gdy wiadomości są pobierane z kolejki. 10ms thread.sleep command po count ++ działa znacznie sprawniej, ale zajmuje dużo więcej czasu i nadal uważam, że musi istnieć lepszy sposób na policzenie tego, by natarczywie zerknąć milion razy ... (czy jesteśmy tam jeszcze, czy my tam jeszcze, jesteśmy tam jeszcze - doh) – barrypicker
Ten kod zakończy się niepowodzeniem, jeśli kolejka zawiera 0 komunikatów, ponieważ spróbuje PeekWithoutTimeout z PeekAction.Next, nawet jeśli PeekWithTimeout z PeekAction.Current zwróci wartość null. Dodano zerową kontrolę, aby odpowiedzieć –
nie ma API dostępne, ale można użyć GetMessageEnumerator2
który jest szybki ENO ugh. Próbka:
MessageQueue q = new MessageQueue(...);
int count = q.Count();
Realizacja
public static class MsmqEx
{
public static int Count(this MessageQueue queue)
{
int count = 0;
var enumerator = queue.GetMessageEnumerator2();
while (enumerator.MoveNext())
count++;
return count;
}
}
Próbowałem też inne opcje, ale każda ma pewne wady
- licznik wydajności może wyjątek throw „Instancja '...' robi nie istnieje w podanej kategorii. "
- przeczytaniu wszystkich wiadomości, a następnie biorąc count jest bardzo powolny, ale również usuwa wiadomości z kolejki
- Wydaje się, że problem z
Peek
metody, która zgłasza wyjątek
Czy nie ma tu warunków wyścigu? Co się stanie, jeśli podczas dodawania lub usuwania rzeczy zostaną dodane/usunięte? Lub jeśli rzeczy są dodawane/usuwane po policzeniu? Czy istnieje sposób zawieszenia wszelkiej interakcji z kolejką, gdy się liczymy? –
Ta metoda wydaje się być wątkowo bezpieczna w tym sensie, że odzwierciedla dynamiczne zmiany w kolejce. Od [doc] (https://goo.gl/GywJEn) * "Na przykład moduł wyliczający może automatycznie uzyskać dostęp do komunikatu o niższym priorytecie umieszczonego poza aktualną pozycją kursora, ale nie jest to wiadomość o wyższym priorytecie wstawiona przed tą pozycją." *. Osobiście testowałem to pod obciążeniem podczas wstawiania i usuwania i nie miałem problemów z wątkami. Oczywiście, będzie to odzwierciedlać około. liczba wiadomości, jeśli używana jest kolejka.Jeśli potrzebujesz dokładnego liczenia, musisz uzyskać statyczną migawkę, wywołując 'GetAllMessages' – oleksii
//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();
jest szybsza niż ty wybrałeś. Otrzymujesz od MSMQManagement refferance wewnątrz "C: \ Program Files (x86) \ Microsoft SDK \ Windows" tylko przegląda w tym adres dostaniesz go. Aby uzyskać więcej informacji, odwiedź stronę http://msdn.microsoft.com/en-us/library/ms711378%28VS.85%29.aspx.
To zadziałało dla mnie. Używając modułu Enumarator, upewnij się, że kolejka jest pusta.
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
To jest pytanie C#, twoja odpowiedź brzmi: VB – namford
Jeśli potrzebujesz szybki sposób (25k Połączenia/sekund na moim komputerze), polecam wersję Ayende opartego na MQMgmtGetInfo() i PROPID_MGMT_QUEUE_MESSAGE_COUNT:
dla C# https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs
dla VB https://gist.github.com/Lercher/5e1af6a2ba193b38be29
Pochodzenie prawdopodobnie było http://functionalflow.co.uk/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/, ale nie jestem przekonany, że ta implementacja z 2008 roku już działa.
Nie szukaj innej odpowiedzi! Poza odpowiedzią @ Zartaga, każda inna metoda jest albo powolna, albo niewiarygodna (testowałem wszystkie, uwierz mi!) – meraydin
Pakiet nuget [Rsft.Lib.Msmq.MessageCounter] (https://www.nuget.org/ packages/Rsft.Lib.Msmq.MessageCounter /) implementuje to. –
Liczbę wiadomości w kolejce można znaleźć, korzystając z następującego kodu.
MessageQueue messageQueue = new MessageQueue(".\\private$\\TestQueue");
var noOFMessages = messageQueue.GetAllMessages().LongCount();
W takim przypadku wszystkie wiadomości są wysyłane z kolejki. To jest za drogie. –
Naprawdę miałem problem z uzyskaniem akceptowanej odpowiedzi z powodu błędu xxx does not exist in the specified Category
. Żadne z powyższych rozwiązań nie sprawdziło się u mnie.
Jednak wydaje się, że proste jest określenie nazwy komputera, jak poniżej.
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;
}
}
- 1. Czy istnieje lepszy sposób liczenia wiadomości w kolejce wiadomości (MSMQ)?
- 2. Czy istnieje sposób sprawdzenia, ile powtórzeń wykonaliśmy w pętli for?
- 3. Czy istnieje sposób sprawdzenia, ile procesora zużywa procesor na rdzeń?
- 4. Czy istnieje sposób sprawdzenia, ile parametrów jest wymaganych dla metody?
- 5. Czy istnieje sposób sprawdzenia, ile pamięci używa zmienna?
- 6. Jak mogę się dowiedzieć, ile plików znajduje się w katalogu?
- 7. Java - Najszybszy sposób sprawdzenia, czy URL istnieje
- 8. pytoniczny sposób sprawdzenia, czy coś istnieje?
- 9. Czy istnieje sposób sprawdzenia, czy odebrano transmisje LocalBroadcastManager?
- 10. Uzyskiwanie wiadomości według priorytetu z MSMQ
- 11. Sposób sprawdzania, czy adres IP znajduje się w określonej podsieci
- 12. czy istnieje jakieś zdarzenie lub wywołanie zwrotne w MSMQ dla nowej wiadomości dodanej do kolejki
- 13. Dwa typy wiadomości w kolejce wiadomości
- 14. Wiedzieć, ile osób znajduje się na wideo
- 15. Czy istnieje sposób sprawdzenia, czy zmienna jest zdefiniowana w Javie?
- 16. Czy istnieje przenośny sposób sprawdzenia, ile plików JVM ma otworzyć z wnętrza maszyny wirtualnej?
- 17. Najlepszy sposób sprawdzenia, czy usługa zawiesiła się
- 18. Jaki jest najszybszy sposób sprawdzenia, czy punkt znajduje się wewnątrz wielokąta w pytonie?
- 19. Czy istnieje lepszy sposób sprawdzenia, czy plik jest zapisywany?
- 20. Prosty sposób na sprawdzenie, czy element znajduje się z przodu?
- 21. Czy istnieje sposób sprawdzenia, czy element zakończył przejście CSS3?
- 22. Perl 6: jaki jest najlepszy sposób sprawdzenia, czy element znajduje się na liście?
- 23. Czy istnieje sposób sprawdzenia, czy alarm jest już ustawiony?
- 24. Czy istnieje właściwy sposób sprawdzenia istnienia pliku/katalogu w Javie?
- 25. Czy istnieje sposób sprawdzenia, czy operacja OpenGL została zakończona?
- 26. Czy istnieje sposób sprawdzenia, czy wybór HTML jest obecnie otwarty?
- 27. Czy istnieje sposób sprawdzenia, czy komponent reagowania nie jest podłączony?
- 28. Czy istnieje sposób sprawdzenia, czy dwa elementy DOM są równe?
- 29. Czy istnieje sposób sprawdzenia, czy ReactElement renderuje wartość "null"?
- 30. Jaki jest najlepszy sposób sprawdzenia, czy URL istnieje w PHP?
Działa dobrze dla jednej kolejki, ale dla kolejki błędów dostaję "Instance" nazwa_sterowania \ private $ \ error "nie istnieje w podanej kategorii.". Czy to dlatego, że kolejka nie ma żadnych elementów w kolejce przez jakiś czas, czy też muszę napisać w specjalny sposób do kolejki błędów? –
Dodałem wiadomość w kolejce błędów, a następnie kod działa również dla tej kolejki. Chyba musisz złapać ten wyjątek (InvalidOperationException), a następnie jest pusty. Źle, kolejka może również nie istnieć, jeśli otrzymasz ten wyjątek. –
Znalazłem, że składnia, jak ". \ Private $ \ testqueue2", co otrzymam z someQueue.Path spowoduje wyjątek. Skończyło się na używaniu someQueue.FormatName i wyodrębnianiu "machinename \ private $ \ testqueue2" z jego zawartości. Stwierdziłem również, że to podejście nie jest w 100% niezawodne, gdy kolejka jest właśnie uruchamiana lub pobierana, co sprawiło, że pomyślałem, że lepiej byłoby, gdyby implementacja oparta była na combo, ale nie miałem czasu inwestować w więcej testów. . – pasx