这里的每个人都在提供解决方案方面做得非常出色,并且我自己刚刚完成了与这个问题的斗争,我想投入我自己的 2c 并展示我想出的解决方案非常有效。
首先,当创建队列时,我确保像这样打开权限(我不关心我们应用程序上下文中的队列安全性......这是一个经过计算的决定):
queue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl, AccessControlEntryType.Set);
如果没有那条线,我会收到各种无法访问的错误,甚至无法从计算机管理屏幕浏览队列。顺便说一句,如果这种情况发生在您身上,并且您想知道如何杀死您无权访问的队列:
- 停止服务“消息队列”
- 转到“C:\Windows\System32\msmq\storage\lqs”
- 在记事本中打开每个文件并查找您的队列名称(很可能是最近修改的文件)
- 删除该文件并重新启动消息服务
为您的队列消息项创建一个基类并将其标记为 [Serializable]。在应用程序加载缓存所有消息类型的列表,使用如下所示:
var types = typeof(QueueItemBase).Assembly
.GetTypes()
.Where(t => typeof(QueueItemBase).IsAssignableFrom(t) && t.IsAbstract == false)
.ToArray();
...
// Create and cache a message formatter instance
_messageFormatter = new XmlMessageFormatter(types);
现在您可以开始接收消息了。我的第一直觉是轮询消息,但 api 并不喜欢那样工作。因此,我创建了一个后台线程并在队列上调用阻塞方法 Receive,一旦消息可用,该方法将返回。从那里解码消息很简单:
var message = queue.Receive();
if (message == null)
continue;
// Tell the message about our formatter containing all our message types before we
// try and deserialise
message.Formatter = _messageFormatter;
var item = message.Body as QueueItemBase;
这应该是您获得良好实现、类型安全的 MSMQ 集成所需的全部内容!