C# Bot Framework AdaptiveDialog:仅当对话框位于堆栈顶部时触发活动?

C# Bot Framework AdaptiveDialog:仅当对话框位于堆栈顶部时触发活动?,c#,botframework,C#,Botframework,我在Bot Framework v4中有以下“”样式的根对话框: public class CustomRootDialog : AdaptiveDialog { public CustomRootDialog() : base(nameof(CustomRootDialog)) { Recognizer = new RegexRecognizer() { Intents = new List<IntentPatter

我在Bot Framework v4中有以下“”样式的根对话框:

public class CustomRootDialog : AdaptiveDialog
{
    public CustomRootDialog() : base(nameof(CustomRootDialog))
    {
        Recognizer = new RegexRecognizer()
        {
            Intents = new List<IntentPattern>()
            {
                new IntentPattern() { Intent = "HelpIntent", Pattern = "(?i)help" },
                new IntentPattern() { Intent = "SecondaryDialog", Pattern = "(?i)run" },
            },
        };
        
        Triggers.Add(new OnIntent("HelpIntent", actions: new List<Dialog>()
        {
            new SendActivity("Hi, here's the help from the root!")
        }));

        Triggers.Add(new OnIntent("SecondaryDialog", actions: new List<Dialog>()
        {
            new SecondaryDialog()
        }));
    }
}
公共类CustomRootDialog:AdaptiveDialog
{
public CustomRootDialog():base(name of(CustomRootDialog))
{
识别器=新的RegexRecognizer()
{
意图=新列表()
{
新的IntentPattern(){Intent=“HelpIntent”,Pattern=“(?i)help”},
新的IntentPattern(){Intent=“SecondaryDialog”,Pattern=“(?i)run”},
},
};
添加(新的OnIntent(“HelpIntent”),操作:newlist()
{
新建SendActivity(“嗨,这是来自根目录的帮助!”)
}));
Add(new-OnIntent(“SecondaryDialog”,actions:newlist())
{
新建SecondaryDialog()
}));
}
}
当用户开始与机器人对话并说“帮助”时,对话框会按预期回答:

我还有一个对话框,可以使用“run”-关键字启动。下面是另一个对话框:

public class SecondaryDialog : Dialog
{
    public override async Task<DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = new CancellationToken())
    {
        var input = dc.Context.Activity.Text;

        if (input == "help")
        {
            await dc.Context.SendActivityAsync("Secondary dialog help", cancellationToken: cancellationToken);
            return EndOfTurn;
        }

        if (input == "exit")
        {
            return new DialogTurnResult(DialogTurnStatus.Complete);
        }

        return EndOfTurn;
    }
}
public class secondary对话框:对话框
{
公共重写异步任务ContinueDialogAsync(DialogContext dc,CancellationToken CancellationToken=new CancellationToken())
{
var输入=dc.Context.Activity.Text;
如果(输入=“帮助”)
{
等待dc.Context.SendActivityAsync(“辅助对话框帮助”,取消令牌:取消令牌);
回报内翻;
}
如果(输入=“退出”)
{
返回新的DialogTurnResult(DialogTurnStatus.Complete);
}
回报内翻;
}
}
现在,当用户使用“运行”移动到第二个对话框,然后键入“帮助”时,两个对话框都会回答:

我希望只有第二个对话框会回答。我可以从辅助对话框中看到其Context.Responsed为true,这意味着我可以从辅助对话框中跳过SendActivity。但我想做相反的事情:只有当当前位于堆栈顶部的对话框没有响应时,根对话框才应该响应

是否可以修改AdaptiveDialog的触发器,使其仅在没有其他对话框响应或没有其他对话框运行时触发

更新:

bot是使用Microsoft文档提供的指南创建的,如下所示:

以下是bot的注册方式:

        services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
        ComponentRegistration.Add(new DialogsComponentRegistration());
        ComponentRegistration.Add(new AdaptiveComponentRegistration());

        services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
        services.AddSingleton<IStorage, MemoryStorage>();
        services.AddSingleton<UserState>();
        services.AddSingleton<ConversationState>();
        services.AddSingleton<IBot, DialogBot<CustomRootDialog>>();
services.AddSingleton();
添加(新对话框ComponentRegistration());
添加(新的AdaptiveComponentRegistration());
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();

公共类对话框bot:ActivityHandler
其中T:Dialog
{
专用只读DialogManager DialogManager;
受保护的只读ILogger记录器;
公共对话框bot(T rootDialog、ILogger记录器)
{
记录器=记录器;
DialogManager=新的DialogManager(rootDialog);
}
公共覆盖异步任务OnTurnAsync(ITurnContext turnContext,CancellationToken CancellationToken=default)
{
Logger.LogInformation(“使用活动运行对话框”);
await DialogManager.OnTurnAsync(turnContext,cancellationToken:cancellationToken).ConfigureAwait(false);
}
}

您是否通过对话框管理器运行
CustomRootDialog
?@KyleDelaney谢谢您的提问。是的,有对话管理器。该代码基于Microsoft提供的指导。我更新了这个问题,没有更多的细节:)你读了吗?看起来您想要的行为已经是自适应对话框的内置行为了。它说,当“允许中断”属性为true时,在检查任何祖先之前,将检查最直接的父级是否有触发器。它是一个使
SecondaryDialog
成为自适应对话框的选项,还是需要它自己的类型?自适应对话框似乎被设计成一路都有自适应对话框,否则事情会变得很糟糕。你还在做这个吗?
public class DialogBot<T> : ActivityHandler
    where T : Dialog
{
    private readonly DialogManager DialogManager;
    protected readonly ILogger Logger;

    public DialogBot(T rootDialog, ILogger<DialogBot<T>> logger)
    {
        Logger = logger;

        DialogManager = new DialogManager(rootDialog);
    }

    public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
    {
        Logger.LogInformation("Running dialog with Activity.");
        await DialogManager.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
    }
}