2009-12-16 86 views
3

我有一个关于探路MSMQ ... 我设计了一个异步arhitecture这样的:MSMQ查询特定信息

客户端 - > WCF服务(在WINSERVICE托管) - > MSMQ

所以基本上WCF服务接受请求,处理它们,将它们添加到一个INPUT队列并返回一个GUID。同一个WCF服务(通过侦听器)从队列中获取第一条消息(做一些事情......),然后将其放回另一个队列(OUTPUT)。

问题是,如何从客户端请求时从OUTPUT队列中检索结果...因为MSMQ不允许随机访问它的消息,唯一的解决方案是遍历所有消息并将其推回直到找到我需要的确切一个。我不想为这个OUTPUT队列使用DB,因为客户端施加了一些限制...

回答

5

您可以通过使用

var mq = new MessageQueue(outputQueueName); 
mq.PeekById(yourId); 

通过ID接收在输出-队列为你的消息看:

mq.ReceiveById(yourId); 
+0

谢谢,这似乎是一个很好的解决方案。我会试一试。 – GeoXYZ 2010-01-04 13:31:58

6

队列本质上是一种“先进先出”类型的数据结构,而您想要的是一个“随机访问”数据结构。它只是没有为你想要在这里实现的目标而设计,所以没有任何“干净”的方式来做到这一点。即使有办法,这将是一个黑客。

如果您详细阐述客户端施加的限制,可能还有其他的选择。 为什么不想使用数据库?你可以使用本地的SQLite DB,或者甚至是内存的?

编辑:如果你有一个客户端口述实施细则自己不利则实际上只有三种方法可以去:他们周围

  1. 工作。在这种情况下,这可能涉及使用SQLite数据库 - 这只是一个文件,客户端可能甚至不会将其视为“数据库”。
  2. 深入探索并找出潜在的问题,即。 为什么他们不想使用数据库吗?他们真正的担忧和潜在假设是什么?
  3. 接受一个不好的解决方案,并向客户解释这是由于他们自己的限制。这从来都不好,也不容易,所以这真的是最后的手段。
+0

因为客户不希望我们使用任何数据库(尽管我试图解释原因......)...结果列表务必通过系统故障持久化,并且MSMQ消息可以设置为可恢复... – GeoXYZ 2009-12-16 07:46:42

+0

我想在MSMQ内部存储自定义对象(仅用于持久性),但这会引发并发访问的问题,因为我有多个线程同时运行,可以访问此对象......在其上添加一个writerLock会影响整个系统的性能...... – GeoXYZ 2009-12-16 07:48:31

3

你可能可以使用CorrelationId并设置它,当你发送邮件。然后,接收您可以ReceiveByCorrelationId挑选具体消息如下相同的消息:

message = queue.ReceiveByCorrelationId(correlationId); 

此外,CorrelationId是一个具有以下格式的字符串:

Guid()\\Number