Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Azure函数:如何更好地实现重试队列消息的延迟_C#_Azure_Azure Functions_Azure Queues - Fatal编程技术网

C# Azure函数:如何更好地实现重试队列消息的延迟

C# Azure函数:如何更好地实现重试队列消息的延迟,c#,azure,azure-functions,azure-queues,C#,Azure,Azure Functions,Azure Queues,My Azure函数应该侦听队列中的消息,然后获取消息,尝试调用消息中包含值的外部服务,如果外部服务返回“OK”,则我们必须将消息写入另一个队列(对于下一个Azure函数),如果返回“Fail”我们必须返回到当前队列,并在5分钟后通过Azure函数再次重试。如何实施?我是用定时器完成的,但解决方案不喜欢我: [FunctionName("FunctionOffice365VerificateDomain_and_AddService_and_GexMxRecord")] publ

My Azure函数应该侦听队列中的消息,然后获取消息,尝试调用消息中包含值的外部服务,如果外部服务返回“OK”,则我们必须将消息写入另一个队列(对于下一个Azure函数),如果返回“Fail”我们必须返回到当前队列,并在5分钟后通过Azure函数再次重试。如何实施?我是用定时器完成的,但解决方案不喜欢我:

    [FunctionName("FunctionOffice365VerificateDomain_and_AddService_and_GexMxRecord")]
    public async static Task Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer,
        [Queue("domain-verificate-Office365-add-services-get-mx-record", Connection = "StorageConnectionString")]CloudQueue listenQueue,
        [Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]CloudQueue outputQueue,
        ILogger log)
    {
        while (true)
        {
            // do "invisible" message for next 30 sec
            var message = await listenQueue.GetMessageAsync();
            if (message != null)
            {
                DomainForRegistration domainForRegistration = JsonConvert.DeserializeObject<DomainForRegistration>(message.AsString);
                try
                {
                    await _office365DomainService.VerifyDomainAsync(domainForRegistration.DomainName);
                    // remove message
                    await listenQueue.DeleteMessageAsync(message);

                    await _office365DomainService.UpdateIndicateSupportedServicesDomainAsync(domainForRegistration.DomainName);

                    var mxRecord = await _office365DomainService.GetMxRecordForDomainAsync(domainForRegistration.DomainName);
                }
                catch (DomainVerificationRecordNotFoundException)
                {
                     // thrown when VerifyDomainAsync failed
                }
            }
            else
                break;
        }
    }
[FunctionName(“FunctionOffice365VerificateDomain”和“添加服务”和“GexMxRecord”)]
公共异步静态任务运行([TimerTrigger(“0*/5****”)TimerInfo myTimer,
[Queue(“domain-verificate-Office365-add-services-get-mx-record”,Connection=“StorageConnectionString”)]CloudQueue listenQueue,
[Queue(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]CloudQueue outputQueue,
ILogger日志)
{
while(true)
{
//在接下来的30秒内执行“不可见”消息
var message=await listenQueue.GetMessageAsync();
如果(消息!=null)
{
DomainForRegistration DomainForRegistration=JsonConvert.DeserializeObject(message.AsString);
尝试
{
wait_office365DomainService.VerifyDomainAsync(domainForRegistration.DomainName);
//删除消息
wait listenQueue.DeleteMessageAsync(消息);
wait_office365; domainservice.updateIndicatedSupportedServicesDomainAsync(domainForRegistration.DomainName);
var mxRecord=wait_office365DomainService.GetMxRecordForDomainAsync(domainForRegistration.DomainName);
}
捕获(DomainVerificationRecordNotFoundException)
{
//VerifyDomainAsync失败时引发
}
}
其他的
打破
}
}

如何更仔细地执行此操作,而不使用这些
(true)
,而是在验证失败后超时?

同意@DavidG,尝试使用队列触发器来实现您的目标。 W可以依赖于队列的长度

visibilityTimeout是消息处理失败时重试之间的时间间隔 maxDequeueCount是将消息移动到毒药队列之前尝试处理消息的次数

这样,函数应该如下所示

public static async Task Run(
    [QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
    [Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue
)
{
    // do stuff then output message
    await outputQueue.AddAsync(myQueueItem);
}
公共静态异步任务运行(
[QueueTrigger(“domain-verificate-Office365-add-services-get-mx-record”)]字符串myQueueItem,ILogger日志,
[队列(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]IAsyncCollector输出队列
)
{
//做一些事情然后输出消息
等待outputQueue.AddAsync(myQueueItem);
}
如果您不想将异常抛出到主机,我们可以使用CloudQueue方法

指定从现在起消息不可见的时间间隔

公共静态异步任务运行(
[QueueTrigger(“domain-verificate-Office365-add-services-get-mx-record”)]字符串myQueueItem,ILogger日志,
[队列(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]IAsyncCollector输出队列,
[Queue(“domain-verificate-Office365-add-services-get-mx-record”,Connection=“StorageConnectionString”)]CloudQueue listenQueue
)
{
尝试
{
//做一些事情然后输出消息
等待outputQueue.AddAsync(myQueueItem);
}
捕获(DomainVerificationRecordNotFoundException)
{
//将消息添加到当前队列中,并且仅在5分钟后可见
wait listenQueue.AddMessageAsync(新的CloudQueueMessage(myQueueItem)),null,TimeSpan.FromMinutes(5),null,null;
}
}

如果这是一个队列,为什么不为每条消息触发该函数?不确定为什么需要循环。@DavidG,因为失败后我必须添加相同的消息,函数将立即(毫不延迟)再次调用谢谢!我不知道将消息添加到队列的“延迟”参数:)
public static async Task Run(
    [QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
    [Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue
)
{
    // do stuff then output message
    await outputQueue.AddAsync(myQueueItem);
}
    public static async Task Run(
        [QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
        [Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue,
        [Queue("domain-verificate-Office365-add-services-get-mx-record", Connection = "StorageConnectionString")]CloudQueue listenQueue
    )
    {

        try 
        {
            // do stuff then output message
            await outputQueue.AddAsync(myQueueItem);
        }
        catch(DomainVerificationRecordNotFoundException)
        {
            // add the message in current queue and can only be visible after 5 minutes
            await listenQueue.AddMessageAsync(new CloudQueueMessage(myQueueItem), null, TimeSpan.FromMinutes(5), null, null);
        }
    }