Асинхронная проверка очередей Azure с использованием насоса сообщений

В моем приложении я хочу проверить основную очередь и очередь недоставленных сообщений, используя установленный насос сообщений. Проблема, с которой я сталкиваюсь, заключается в потоке реализации по умолчанию.

Я не уверен, как заставить их работать одновременно

Это стандартная реализация насоса сообщений из Azure.

Client.OnMessage((receivedMessage) =>
                {

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

Метод waitone ожидает, пока не будет вызван метод set manualResetEvent. Я не уверен, что определяет метод, я думаю, что это происходит за кулисами процесса onmessage.

Что происходит сейчас, запускается ли метод onmessage, он запускает процесс waitone и остается там до тех пор, пока не придет другое сообщение, что должно произойти, но как мне запустить два из них одновременно?

2 ответа

Решение

Допустим, у вас есть консольное приложение, которое запускает ваш код:

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, рабочую роль Azure), чтобы приложение не закрывалось. Если вы внедрите этот код в службу Windows или в веб-приложение, вам не нужно блокировать основной поток, потому что существуют другие механизмы для поддержания работы вашего приложения.

Когда приходит новое сообщение, насос сообщений раскручивает новый поток, чтобы выполнить код внутри 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();
    }
}

Возможно, я не слежу за вашим вопросом, но у вас есть обратный вызов, зарегистрированный в OnMessage API, и продолжение вашей основной программы, если было получено одно сообщение. Зачем вам делать WaitOne вне обратного вызова? Обратный вызов предназначен для запуска в фоновом режиме и получения ваших сообщений.

Если вы хотите получить только одно или два сообщения, возможно, используя QueueClient (или похожий) это лучший вариант?

Другие вопросы по тегам