如何为Azure Durable Function业务流程或WaitForInstanceCompletionAsync设置30秒超时?
Azure Durable Function 超时实现方案
需求1:业务流程30秒超时后自动结束
在编排器函数中,通过CreateTimer创建超时任务,结合Task.WhenAny监听业务任务与超时任务的完成状态,超时后直接终止流程:
[Function("ORCHESTRATOR_TRIGGER_NAME")] public async Task Run( [OrchestrationTrigger] TaskOrchestrationContext context) { // 定义30秒超时任务 var timeoutTask = context.CreateTimer(context.CurrentUtcDateTime.AddSeconds(30), CancellationToken.None); // 你的长耗时业务任务集合 var businessTasks = new List<Task>(); // 示例:添加业务任务到集合 // businessTasks.Add(CallLongRunningActivityAsync(context)); // 等待业务任务或超时任务先完成 var completedTask = await Task.WhenAny(Task.WhenAll(businessTasks), timeoutTask); // 如果超时任务先完成,直接终止流程 if (completedTask == timeoutTask) { _logger.LogWarning("业务流程已超时,自动终止"); return; } // 业务任务正常完成,处理结果 _logger.LogInformation("业务流程正常完成"); }
需求2:为WaitForInstanceCompletionAsync设置超时
有两种实现方式:
方式1:使用方法自带的超时参数
WaitForInstanceCompletionAsync支持直接传入超时时间参数,超时后会抛出TimeoutException,可捕获并处理:
[Function("TimerTrigger_EveryMinute")] public async Task TimerTrigger_EveryMinute( [TimerTrigger("0 * * * * *")] TimerInfo timerInfo, [DurableClient] DurableTaskClient starter) { _logger.LogError("Running timer trigger"); string instanceId = await starter.ScheduleNewOrchestrationInstanceAsync("ORCHESTRATOR_TRIGGER_NAME"); try { // 设置30秒超时 await starter.WaitForInstanceCompletionAsync(instanceId, TimeSpan.FromSeconds(30)); _logger.LogInformation($"Completed orchestration with ID = '{instanceId}'"); } catch (TimeoutException) { _logger.LogWarning($"Orchestration {instanceId} timed out during wait"); // 可添加超时后的处理逻辑,比如终止实例 // await starter.TerminateInstanceAsync(instanceId, "因等待超时终止"); } }
方式2:使用Task.WhenAny手动处理超时
通过Task.WhenAny同时等待WaitForInstanceCompletionAsync和延迟任务,避免抛出异常:
[Function("TimerTrigger_EveryMinute")] public async Task TimerTrigger_EveryMinute( [TimerTrigger("0 * * * * *")] TimerInfo timerInfo, [DurableClient] DurableTaskClient starter) { _logger.LogError("Running timer trigger"); string instanceId = await starter.ScheduleNewOrchestrationInstanceAsync("ORCHESTRATOR_TRIGGER_NAME"); var waitTask = starter.WaitForInstanceCompletionAsync(instanceId); var timeoutTask = Task.Delay(TimeSpan.FromSeconds(30)); var completedTask = await Task.WhenAny(waitTask, timeoutTask); if (completedTask == waitTask) { _logger.LogInformation($"Completed orchestration with ID = '{instanceId}'"); // 确保等待任务的异常被捕获(如果有) await waitTask; } else { _logger.LogWarning($"Orchestration {instanceId} timed out during wait"); // 可添加超时后的处理逻辑 // await starter.TerminateInstanceAsync(instanceId, "因等待超时终止"); } }
内容的提问来源于stack exchange,提问作者user21940304
相关产品推荐
相关产品推荐

