我正在使用Oracle ODP.Net进行入队和出队。
过程A:入队 进程B:使用MessageAvailable事件出列队列
如果进程A和B正在运行,则没有问题。在“过程B”中,事件总是被触发。
但是,如果“进程B”关闭且“进程A”打开,则当“进程B”重新启动时,在关闭时间内插入的队列将丢失。
是否可以选择为过去插入的所有队列触发事件?
非常感谢
答案 0 :(得分:3)
似乎有两种方法可以解决这个问题:
我一直在讨论这个话题。如果您仍然需要“手动”测试新消息,那么首先使用MessageAvaiable事件回调有什么好处?我考虑的一条路线是将Listen()方法包装在异步调用中,以便调用者不会在线程上阻塞(直到收到消息或发生超时)。我在自定义的Receive()方法中包装了Listen()和Dequeue(),并创建了自己的MessageReceived事件处理程序,以将消息详细信息传递给调用线程。看起来有点多余,因为ODP.NET提供了开箱即用的回调,但我不必处理你描述的问题(或者编写代码来“手动”测试“孤立”消息。
欢迎任何关于方法的意见/想法。
答案 1 :(得分:0)
我一直在看这个,最后做了类似Greg的事情。我没有使用过Listen()方法,因为我认为它不能为我提供任何超越简单的Dequeue() - 当你想要代表多个消费者监听时,Listen()似乎是有益的,我的实例不相关(见Oracle Docs)。
因此,在我的“进程B”中,我首先在启动轮询过程之前注册通知,以检查是否存在任何现有消息。它不是Listen(),它只是在一个受控循环中调用Dequeue(),并设置了几秒钟的等待时间。如果轮询进程遇到Oracle超时,则等待期已过,并且轮询停止。如果等待时间尚未到期,我可能需要考虑处理超时(尽管如果可能发生这种情况,并非100%确定)。
我注意到在轮询时排队的任何消息都会调用消息通知方法,但是当它连接并尝试检索消息时,轮询过程似乎总是采用它。因此,在消息通知方法中,我捕获并忽略编号为25263(no message in queue <...> with message ID <...>
)的任何OracleExceptions。