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