Azure Durable Function:多ActivityTrigger编排及WaitForInstanceCompletionAsync超时设置
Azure Durable Function 编排超时与WaitForInstanceCompletionAsync超时设置
一、为Orchestration设置30秒超时
在编排函数中,可以通过Task.WhenAny结合Durable官方推荐的context.CreateTimer实现超时控制,超时后直接退出编排。示例修改如下:
[Function("ORCHESTRATOR_TRIGGER_NAME")] public async Task Run( [OrchestrationTrigger] TaskOrchestrationContext context) { var parallelTasks = new List<Task<int>>(); for (int i = 0; i < 5; i++) { Task<int> task = context.CallActivityAsync<int>("getdata", i); parallelTasks.Add(task); } // 创建30秒超时定时器(使用Durable内置定时器保证编排重启状态恢复) var timeoutTask = context.CreateTimer(context.CurrentUtcDateTime.AddSeconds(30), CancellationToken.None); // 等待并行任务完成或超时触发 var completedTask = await Task.WhenAny(Task.WhenAll(parallelTasks), timeoutTask); // 超时触发则直接退出编排 if (completedTask == timeoutTask) { _logger.LogInformation("Orchestration timed out after 30 seconds, exiting."); return; } // 并行任务正常完成,处理结果 var results = await (Task<int[]>)completedTask; _logger.LogInformation($"All activities completed, results: {string.Join(", ", results)}"); }
注意:已启动的活动任务无法被取消,超时后编排会直接结束,但活动任务会继续执行直到完成。
二、为WaitForInstanceCompletionAsync设置超时
WaitForInstanceCompletionAsync支持两种方式设置超时,以下是具体实现:
方式1:直接指定超时时间
使用带TimeSpan参数的重载,超时后抛出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, timeout: TimeSpan.FromSeconds(30)); _logger.LogInformation($"Completed orchestration with ID = '{instanceId}'"); } catch (TimeoutException) { _logger.LogWarning($"Wait for orchestration {instanceId} timed out after 30 seconds."); } }
方式2:使用CancellationToken
通过CancellationTokenSource创建超时令牌,超时后抛出OperationCanceledException:
[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"); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); try { await starter.WaitForInstanceCompletionAsync(instanceId, cancellationToken: cts.Token); _logger.LogInformation($"Completed orchestration with ID = '{instanceId}'"); } catch (OperationCanceledException) { _logger.LogWarning($"Wait for orchestration {instanceId} was cancelled due to timeout."); } }
这里的超时是客户端等待编排完成的超时,和编排内部的超时是独立逻辑,可根据需求结合使用。
内容的提问来源于stack exchange,提问作者user21940304
相关产品推荐
相关产品推荐

