You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Durable Task Framework(DTF)中获取已有编排实例?

DTF 暂停/恢复编排实现方案

前置说明:以下方案仅基于Durable Task Framework(DTF)实现,不涉及Azure Durable Functions相关能力

你不需要手动获取已暂停编排的运行时实例对象,DTF 提供的 TaskHub 客户端原生支持直接通过实例ID触发事件、管理实例生命周期,完全适配你的业务场景,具体实现分两部分:

1. 编排侧暂停逻辑

在需要检查标志位的节点使用DTF原生的WaitForExternalEvent方法实现持久化暂停,不要自行实现线程休眠/轮询逻辑,参考代码如下:

public override async Task RunTask(OrchestrationContext context, BizInput input)
{
    // 执行前置业务逻辑
    var currentFlag = await context.ScheduleTask<bool>(typeof(CheckFlagActivity), input.BizId);
    if (!currentFlag)
    {
        // 首次暂停时将实例ID、输入参数、业务标识、首次暂停时间落库
        await context.ScheduleTask(typeof(SaveSuspendedRecordActivity), new SuspendedRecord
        {
            InstanceId = context.OrchestrationInstance.InstanceId,
            BizInput = input,
            BizId = input.BizId,
            FirstSuspendTime = context.CurrentUtcDateTime,
            RetryCount = 0
        });

        // 等待外部恢复事件,超时时间设置为14天(匹配你14次*24小时的重试规则)
        var getResumeSignal = await context.WaitForExternalEvent<bool>(
            eventName: "FlagMatched",
            timeout: TimeSpan.FromDays(14),
            defaultValue: false
        );

        if (!getResumeSignal)
        {
            // 超时未收到恢复信号,执行清理逻辑后退出编排
            await context.ScheduleTask(typeof(CleanupBizDataActivity), context.OrchestrationInstance.InstanceId);
            return;
        }
    }

    // 标志位初始为真/收到恢复信号后,继续执行后续业务流程
    await context.ScheduleTask(typeof(FollowUpBizActivity), input);
}

注:WaitForExternalEvent是持久化等待,暂停期间不会占用工作线程资源,不会产生额外运行开销,DTF收到对应事件后会自动从持久化存储加载编排上下文继续执行。

2. Service Fabric Actor侧扫描处理逻辑

你的定时Actor不需要关联编排运行时对象,直接复用单例的DTF客户端(和编排运行时连接同一个TaskHub存储即可),通过实例ID直接操作对应编排:

// 单例注入的DTF客户端,初始化时和编排Host使用相同的存储配置、Hub名称
private readonly IOrchestrationServiceClient _dtfClient;

protected override async Task ScanSuspendedInstances()
{
    var suspendedRecords = await _repo.GetAllSuspendedRecords();
    foreach (var record in suspendedRecords)
    {
        var flagIsTrue = await CallExternalFlagApi(record.BizId);
        if (flagIsTrue)
        {
            // 直接传入实例ID触发恢复事件,无需获取实例引用
            await _dtfClient.RaiseEventAsync(
                instanceId: record.InstanceId,
                eventName: "FlagMatched",
                eventData: true
            );
            // 恢复成功后删除数据库中对应的暂停记录
            await _repo.DeleteSuspendedRecord(record.InstanceId);
            continue;
        }

        record.RetryCount += 1;
        if (record.RetryCount >= 14)
        {
            // 重试次数达上限,直接终止对应编排实例
            await _dtfClient.TerminateInstanceAsync(record.InstanceId, "Flag check retry exceeded limit");
            await _repo.DeleteSuspendedRecord(record.InstanceId);
        }
        else
        {
            await _repo.UpdateRecordRetryCount(record);
        }
    }
}

关键注意事项

  • 确保Actor使用的DTF客户端和编排运行时连接同一个持久化存储(MSSQL/ Azure存储等),且配置的TaskHub名称完全一致,否则无法定位到目标编排实例
  • 不要在编排内用循环+延迟的方式轮询标志位,会产生大量冗余的编排历史记录,增加存储开销
  • RaiseEventAsync方法自带幂等性,如果实例已经完成/终止,调用会抛出明确的异常,你可以加个简单的try-catch做异常记录,避免单次调用失败影响整个扫描任务

内容的提问来源于stack exchange,提问作者Rohit Raisinghani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:57:21