【问题标题】:Asynchronous check of Azure Queues using message pump使用消息泵异步检查 Azure 队列
【发布时间】:2016-08-22 19:22:48
【问题描述】:

在我的应用程序中,我想使用设置的消息泵检查主队列和死信队列。我遇到的问题是默认实现上的线程。

我不知道如何让这两者同时运行

这是 Azure 消息泵的默认实现

Client.OnMessage((receivedMessage) =>
                {

                }, new OnMessageOptions { AutoComplete = false});
            CompletedEvent.WaitOne()

waitone 方法一直等到调用 manualResetEvent 设置方法。 我不确定设置方法是什么,我猜这是 onmessage 过程的幕后发生的事情。

现在发生了什么,onmessage 方法是否运行,它会命中 waitone 进程并坐在那里,直到另一条消息进来,这是应该发生的,但我如何让其中两个同时运行?

【问题讨论】:

标签: c# azure azureservicebus


【解决方案1】:

假设您有一个运行您的代码的控制台应用程序:

public class Program
{
    private static void Main()
    {
        var completedEvent = new ManualResetEvent(false);
        ...
        var mainQueue = QueueClient.CreateFromConnectionString("MyConnectionString", "MyQueueName");

        mainQueue.OnMessage((receivedMessage) =>
        {

        }, new OnMessageOptions { AutoComplete = false });

        completedEvent.WaitOne();
    }
}

如果您删除completedEvent.WaitOne();,您的控制台应用程序将立即退出。此行确保您的应用程序不会退出。你可以写一个while(true) {} 代替(不推荐,但这是另一个主题)。

消息泵不会阻塞当前:这就是为什么您需要阻塞线程(在控制台应用程序、azure webjob、azure worker 角色的情况下)以使您的应用程序不退出。如果将此代码实现到 Windows 服务或 Web 应用程序中,则不必阻塞主线程,因为还有其他机制可以保持应用程序运行。

当有新消息到达时,消息泵会启动一个新线程来执行 OnMessage 块内的代码。

所以如果你想同时收听主队列和死信队列,你可以这样做:

public class Program
{
    private static void Main()
    {
        var completedEvent = new ManualResetEvent(false);
        ...
        var mainQueue = QueueClient.CreateFromConnectionString("MyConnectionString", "MyQueueName");
        var deadLetterQueue = QueueClient.CreateFromConnectionString("MyConnectionString", QueueClient.FormatDeadLetterPath("MyQueueName"));

        mainQueue.OnMessage((receivedMessage) =>
        {

        }, new OnMessageOptions { AutoComplete = false });

        deadLetterQueue.OnMessage((receivedMessage) =>
        {

        }, new OnMessageOptions { AutoComplete = false });

        completedEvent.WaitOne();
    }
}

【讨论】:

  • 嗯,有道理,我对waitone方法调用的使用有误解。这非常有效,谢谢
  • 可能在你的上下文中,你不需要阻塞主线程?您的代码是否在工作者角色中运行?
【解决方案2】:

也许我没有关注你的问题,但你在这里得到的是一个使用 OnMessage API 注册的回调,如果收到一条消息,你的主程序会继续。为什么要在回调之外执行 WaitOne?回调旨在在后台紧密循环运行并接收您的消息。

如果您只想接收一两条消息,也许使用QueueClient(或类似的)是更好的选择?

【讨论】:

    猜你喜欢
    • 2018-08-26
    • 2023-03-24
    • 2023-03-27
    • 2013-04-12
    • 2016-06-16
    • 2021-05-25
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多