Я на самом деле в процессе принятия аналогичного решения. В моем случае у меня есть служба WCF, работающая в веб-роли, которая должна загружать вычисления в рабочие роли. Когда результат будет вычислен, веб-роль вернет ответ клиенту.
Мои базовые знания структуры данных говорят мне, что я должен избегать использования чего-то, что было спроектировано как очередь без очереди. Это означает, что очередь всегда должна обслуживаться как FIFO. Таким образом, в основном, если используются очереди как для запросов, так и для ответов, потоки, ожидающие возврата данных клиенту, должны будут ждать, пока сообщение вычисления не окажется в «верхней части» очереди ответа, что не является оптимальным. При хранении ответов с использованием таблиц Azure потоки опрашивают сообщения, создавая ненужные издержки
То, что я считаю возможным решением этой проблемы, это использование очереди для запросов. Это позволяет использовать модель конкурирующих потребителей и, таким образом, балансировать нагрузку. Для сообщений, отправляемых в эту очередь, вы устанавливаете свойство correlationId для сообщения. Для ответа используется часть pub / sub ("themes") служебной шины Azure вместе с корреляционным фильтром . Когда ваш сервер обработал запрос, он опубликовал результат в "responseSubject" с correlationId, указанным в исходном запросе. Теперь этот ответ может быть получен вашим клиентом с помощью вызова CreateSubscribetion (извините, я не могу опубликовать более двух ссылок, по-видимому, Google) с использованием этого фильтра корреляции, и он должен получать уведомления при публикации ответа. Обратите внимание, что часть CreateSubscribetion должна быть выполнена один раз в методе OnStart. Затем вы можете выполнить асинхронный BeginRecieve для этой подписки, и роль будет уведомлена в данном обратном вызове, когда будет доступен ответ на один из его запросов. Параметр correlationId сообщит вам, для какого запроса нужен ответ. Итак, ваша последняя задача - вернуть этот ответ потоку, поддерживающему соединение клиента.
Этого можно достичь, создав словарь с корреляционным идентификатором (вероятно, GUID) в качестве ключа и ответами в качестве значения. Когда ваша веб-роль получает запрос, она создает guid, устанавливает его как correlationId, добавляет его в хэш-набор, запускает сообщение в очередь и затем вызывает Monitor.Wait () для объекта Guid. Затем попросите метод recieve, вызванный подпиской на тему, добавить ответ в словарь и затем вызовите Monitor.Notify () для того же объекта guid. Это пробуждает ваш исходный поток запросов, и теперь вы можете вернуть ответ своему клиенту (или что-то в этом роде. По сути, вы просто хотите, чтобы ваш поток спал и не использовал ресурсы во время ожидания)