1 回答
TA贡献1842条经验 获得超21个赞
假设您在对话框的构造函数中添加对话框,那么您将产生一个无限循环,最终导致您所描述的堆栈溢出。
MainDialog --> DialogA --> DialogAchild --> MainDialog --> infinite loop
您提到的 PR 指的是一个稍微不同的问题。
解决此问题的一种方法是从构造函数中删除导致最终循环的 AddDialog 方法。相反,将调用移至 AddDialogA() 之类的方法,并仅在需要时调用它。
根据您的场景,您可以构建一个提供此类功能的基本对话框。
这是您可以在必要时AuthenticatedDialog添加的产品示例。OnboardingDialog请注意,入职对话框本身继承自 AuthenticatedDialog,当您不卸载AddDialog()呼叫时,这也会导致无限循环。
在基本对话框中抽象它很好,因为它为您提供了一些可以使用的 API。考虑将您的内容命名为 AddComponentDialog 或 UseComponentDialog。这样你就很好地表达了你的意图,潜在的读者一开始就知道你正在使用可重用的组件。
AuthenticatedDialog.cs
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Schema;
using Bot.Dialogs.Authentication;
using Bot.Dialogs.Main;
using Bot.Dialogs.Onboarding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Bot.Dialogs.Shared
{
public class AuthenticatedDialog : EnterpriseDialog
{
private BotStateAccessors _accessors;
private BotServices _botServices;
public AuthenticatedDialog(BotServices botServices, string dialogId, BotStateAccessors accessors) : base(botServices, dialogId)
{
_accessors = accessors;
_botServices = botServices;
AddDialog(new AuthenticationDialog("", accessors));
}
protected async Task<DialogTurnResult> AskForOnboardingAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken, object stepResult = null)
{
return await stepContext.BeginDialogAsync(nameof(OnboardingDialog), stepResult, cancellationToken);
}
protected void AddOnboardingDialog()
{
AddDialog(new OnboardingDialog(_botServices,_accessors));
}
}
}
DialogA.cs
public class DialogA : AuthenticatedDialog
{
public DialogA(BotServices botServices, BotStateAccessors accessors) : base(botServices, nameof(DialogA), accessors)
{
var preferencesDispatchSteps = new WaterfallStep[]
{
WaterfallStepA,
WaterfallStepB
};
AddDialog(new FooDialog);
AddOnboardingDialog();
}
}
- 1 回答
- 0 关注
- 63 浏览
添加回答
举报