Эта проблема была решена путем вызова функции, которая использует многопоточность для опроса очередей Azure по истечении заданного интервала времени и извлечения сообщений (возможно, с установленным экспоненциальным временем задержки).
Подход 1: Реализовать это в веб-приложении немного сложнее, и мне пришлось использовать хак - вызвать функцию из конструктора, чтобы начать опрос.
В файле startup.cs (внутри функции конфигурации) зарегистрируйте службу,
app.ApplicationServices.GetService<IQueueConsumer>();
В функции ConfigureServices, Конфигурирование и создание объекта класса очереди опроса,
services.TryAddTransient<IQueueConsumer>(sp => this.GetQueueProcessor(sp));
А затем, когда конструктор вызывается для создания объекта, начинаем опрашивать очередь в другом потоке.
public QueuePollingFunction(
IOptions<QueueOptions> queueOptions,
CloudQueue queue)
{
this.isEnabled = queueOptions.Value.IsEnabled;
this.StartPollingQueue(queue);
}
public override async Task<bool> ProcessMessageAsync(string message)
{
bool result = false;
try
{
var messageContent = JsonConvert.DeserializeObject<QueueEntity>(message);
result = true;
}
catch (Exception e)
{
Trace.TraceError(e.ToString());
}
return result;
}
private async Task StartPollingQueue(CloudQueue queue)
{
if (this.isEnabled)
{
Task pollQueue = Task.Factory.StartNew(() => Parallel.For(0, this.numberOfParallelTasks, work =>
{
this.Start(queue);
}));
}
}
private async Task Start(CloudQueue queue)
{
while (true)
{
try
{
CloudQueueMessage retrievedMessage = await queue.GetMessageAsync();
if (retrievedMessage != null)
{
// Fail Logic
if (retrievedMessage.DequeueCount > this.maxRetryLimit)
{
await queue.DeleteMessageAsync(retrievedMessage);
}
bool isPass = await this.ProcessMessageAsync(newChannelSettings);
if (isPass)
{
await queue.DeleteMessageAsync(retrievedMessage);
}
}
else
{
// If queue is empty, then the Task can sleep for sleepTime duration
await Task.Delay(this.sleepTime);
}
}
catch (Exception e)
{
Trace.TraceError(e.ToString());
}
}
}
Подход 2: Однако позже пришлось перейти на оптимальный подход, который должен использовать рабочие роли и затем использовать Задачи для запуска фонового потока для выполнения этой задачи.