Last active
July 25, 2017 20:38
-
-
Save Lercher/5e1af6a2ba193b38be29 to your computer and use it in GitHub Desktop.
Counting messages in a Microsoft Message Queue (msmq). About 25k times per second on a 2011 core i7 box with ssd.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Imports System.ComponentModel | |
Imports System.Runtime.InteropServices | |
Public Class MQCounter | |
' see https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs | |
' see http://ayende.com/blog/3884/unmanaged-api-fun-finding-out-msmq-subqueues-names-in-c | |
Public Shared Function Count(Q As String, Host As String) As UInteger | |
Dim props = New MQMGMTPROPS With {.cProp = 1} | |
props.aPropid = Marshal.AllocHGlobal(4) : Marshal.WriteInt32(props.aPropid, PROPID_MGMT_QUEUE_MESSAGE_COUNT) | |
props.status = Marshal.AllocHGlobal(4) : Marshal.WriteInt32(props.status, 0) | |
props.aPropVT = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(MQPROPVariant))) : Marshal.StructureToPtr(New MQPROPVariant With {.vt = VT_NULL}, props.aPropVT, False) | |
Dim QQ = "queue=" & Q | |
dim vt As MQPROPVariant | |
Try | |
Dim result = MQMgmtGetInfo(Host, QQ, props) | |
If result <> 0 Then Throw New Win32Exception(result) | |
Dim statusVal = Marshal.ReadInt32(props.status) | |
If statusval <> 0 Then Throw New ApplicationException("MQMgmtGetInfo status " & statusval.ToString()) | |
vt = DirectCast(Marshal.PtrToStructure(props.aPropVT, GetType(MQPROPVariant)), MQPROPVariant) | |
If vt.vt <> VT_UI4 then Throw New ApplicationException("MQMgmtGetInfo VT is not VT_UI4(19) but " & vt.vt.ToString()) | |
Return vt.value.ulVal | |
Finally | |
' cleanup | |
Marshal.FreeHGlobal(props.aPropid) : props.aPropid = IntPtr.Zero | |
Marshal.FreeHGlobal(props.status) : props.status = IntPtr.Zero | |
Marshal.FreeHGlobal(props.aPropVT) : props.aPropVT = IntPtr.Zero | |
End Try | |
End Function | |
End Class | |
Public NotInheritable Class NativeMethods | |
Private Sub New() | |
End Sub | |
Public Const MQ_MOVE_ACCESS As Integer = 4 | |
Public Const MQ_DENY_NONE As Integer = 0 | |
<DllImport("mqrt.dll", CharSet:=CharSet.Unicode)> _ | |
Public Shared Function MQOpenQueue(formatName As String, access As Integer, shareMode As Integer, ByRef hQueue As IntPtr) As Integer | |
End Function | |
<DllImport("mqrt.dll")> _ | |
Public Shared Function MQCloseQueue(queue As IntPtr) As Integer | |
End Function | |
<DllImport("mqrt.dll")> _ | |
Public Shared Function MQMoveMessage(sourceQueue As IntPtr, targetQueue As IntPtr, lookupID As Long, transaction As IntPtr) As Integer | |
'Public Shared Function MQMoveMessage(sourceQueue As IntPtr, targetQueue As IntPtr, lookupID As Long, transaction As IDtcTransaction) As Integer | |
End Function | |
<DllImport("mqrt.dll")> _ | |
Friend Shared Function MQMgmtGetInfo(<MarshalAs(UnmanagedType.BStr)> computerName As String, <MarshalAs(UnmanagedType.BStr)> objectName As String, ByRef mgmtProps As MQMGMTPROPS) As Integer | |
End Function | |
Public Const VT_NULL As Byte = 1 | |
Public Const VT_UI4 As Byte = 19 | |
Public Const PROPID_MGMT_QUEUE_MESSAGE_COUNT As Integer = 7 | |
Public Const PROPID_MGMT_QUEUE_SUBQUEUE_NAMES As Integer = 27 | |
'size must be 16 | |
<StructLayout(LayoutKind.Sequential, Size:=16)> _ | |
Friend Structure MQPROPVariant | |
Public vt As UShort | |
Public reserved2 As UShort | |
Public reserved3 As UShort | |
Public reserved4 As UShort | |
Public value As UnionedVariant | |
End Structure | |
<StructLayout(LayoutKind.Explicit, Size:=8)> | |
friend Structure UnionedVariant | |
<FieldOffset(0)> public ulVal As UInteger ' VT_UI4 */ | |
<FieldOffset(0)> public calpwstr As ULong ' VT_VECTOR | VT_LPWSTR */ | |
end Structure | |
'size must be 16 in x86 and 28 in x64 | |
<StructLayout(LayoutKind.Sequential)> _ | |
Friend Structure MQMGMTPROPS | |
Public cProp As UInteger | |
Public aPropID As IntPtr | |
Public aPropVT As IntPtr | |
Public status As IntPtr | |
End Structure | |
End Class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment